<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Tomer Filiba's Homepage</title>
 <link href="http://tomerfiliba.com/atom.xml" rel="self"/>
 <link href="http://tomerfiliba.com/"/>
 <updated>2013-05-11T07:59:21-07:00</updated>
 <id>http://tomerfiliba.com/</id>
 <author>
   <name>Tomer Filiba</name>
   <email>tomerfiliba@gmail.com</email>
 </author>

 
 
 <entry>
   <title>Cartesian Tree-Product</title>
   <link href="http://tomerfiliba.com/blog/Cartesian-Tree-Product"/>
   <updated>2013-05-02T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Cartesian-Tree-Product</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2013-05-03-Graph-Cartesian-product2.png&quot; title=&quot;Graph Cartesian product&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I have to admit that my day-to-day life involves very little algorithmic problems, but here and
there I get a chance to think. In this post, I'd like to discuss an interesting problem that I've met
several times already in my programming career, each time in different settings. When I met it again
last week, I decided it's time to formalize it a little. In lack of a better name, I call it
&quot;Cartesian Tree-Product&quot; (not to be confused with &lt;a href=&quot;http://en.wikipedia.org/wiki/Cartesian_product_of_graphs&quot;&gt;Cartesian product of graphs&lt;/a&gt;),
and here's how it goes:&lt;/p&gt;

&lt;p&gt;Say you're given an &lt;a href=&quot;http://en.wikipedia.org/wiki/Binary_expression_tree&quot;&gt;expression tree&lt;/a&gt;. To
limit the scope of the problem, we'll assume the tree is binary, its internal nodes can either be&lt;br/&gt;
&lt;code&gt;AND&lt;/code&gt; or &lt;code&gt;OR&lt;/code&gt;, and its leaves hold &quot;atomic comparators&quot; (which are of no interest to us).
Here's an example expression:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(x=5 OR y=6) AND z=7
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which is represented by the following expression tree:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    AND
    /  \
   OR   \ 
  /  \   \
x=5  y=6  z=7
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the problem is to produce all different sub-trees such that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each sub-tree consists only of &lt;code&gt;AND&lt;/code&gt; internal nodes&lt;/li&gt;
&lt;li&gt;Each sub-tree satisfies the original expression (any assignment that satisfies a sub-tree
must also satisfy the original tree)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OR&lt;/code&gt;-ing together all the sub-trees produces a tree that is mathematically-equivalent to the
original one (any assignment that satisfies the original tree must satisfy the reconstructed tree)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In other words, we want to produce all partial expressions of the original expression, which
will satisfy it and which can together reconstruct it. Big words aside, here's what we want for
the expression above:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;x=5 AND z=7
y=6 AND z=7
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each expression here satisfies the original one (try it), and if we &lt;code&gt;OR&lt;/code&gt; the two, we get a
mathematically-equivalent tree:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(x=5 AND z=7) OR (y=6 AND z=7)


       OR
      /  \
     /    \
  AND      AND
 /   \    /   \
x=5  z=7 y=6  z=7
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(To clarify: By &lt;em&gt;sub-tree&lt;/em&gt; or &lt;em&gt;partial expression&lt;/em&gt;, I mean it is constructed only from
the &lt;em&gt;leaves&lt;/em&gt; of the original tree/expression)&lt;/p&gt;

&lt;p&gt;If you take a second look, it resembles Cartesian products where some &quot;joints&quot; (nodes) in the tree
duplicate the resulting tree. Intuitively, we &quot;split&quot; the tree for every internal &lt;code&gt;OR&lt;/code&gt; and continue
with both copies. For instance, if we take &lt;code&gt;(x=5 OR y=6) AND (z=7 OR w=8)&lt;/code&gt;,
we'll get 4 sub-trees&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;x=5 AND z=7
x=5 AND w=8
y=6 AND z=7
y=6 AND w=8
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, it depends on the structure of the tree; &lt;code&gt;(x=5 OR y=6 OR z=7) AND w=8&lt;/code&gt; produces 3 sub-trees.
This closely relates to the &lt;a href=&quot;http://en.wikipedia.org/wiki/Distributive_law&quot;&gt;rules of distributivity&lt;/a&gt;
in propositional logic, but it seems to me that the &quot;Cartesian product&quot; notion is a generalization
of the concept.&lt;/p&gt;

&lt;h2&gt;How is it Useful?&lt;/h2&gt;

&lt;p&gt;Since we're dealing with expression trees, it's hardly surprising that the two times I had to
use this algorithm related to syntax. In the first case, I wrote a &lt;a href=&quot;http://en.wikipedia.org/wiki/Fuzz_testing&quot;&gt;fuzz-testing&lt;/a&gt;
tool for an interactive program, like the MySQL shell. The program accepted commands, conforming to
a well-defined syntax, and I wanted to generate commands at random and see that it didn't crash.&lt;/p&gt;

&lt;p&gt;For instance, a command might look like &lt;code&gt;map-lun &amp;lt;vol-name|vol-id&amp;gt; lun-id&lt;/code&gt; and we'll want to try
both variants, i.e., &lt;code&gt;map-lun vol-name lun-id&lt;/code&gt; and &lt;code&gt;map-lun vol-id lun-id&lt;/code&gt;. Of course the syntax
is generally much more complex, with nested brackets, optional arguments, etc. It gets interesting,
but we can still map it to the problem outlined above.&lt;/p&gt;

&lt;p&gt;Another real-life use case is running queries against a huge dataset. In order not to complicate
our query engine (written in C for performance), it can perform only intersections (&lt;code&gt;AND&lt;/code&gt;s) of filters.
If you want to query for more complex conditions, you have to run it multiple times with the
partial queries and &quot;sum up&quot; the results. But we don't want the end user &quot;doing the math&quot; for us,
and waiting for one query to finish before we start the next means we have to load data from the
store multiple times. If we could process it in chunks, we'd benefit from cache locality and shorten
query times.&lt;/p&gt;

&lt;h2&gt;The Algorithm&lt;/h2&gt;

&lt;p&gt;The code is strikingly short, but that's not to mean it's easy to follow. The heart of it is
two, recursively-nested for-loops:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cartesian_tree_product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;lhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cartesian_tree_product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cartesian_tree_product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rhs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;op&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;|&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Let's try it out on the expression &lt;code&gt;(x=5 OR y=6) AND (z=7 OR w=8 OR q=9) AND r=10&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;x=5&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;|&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;y=6&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;z=7&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;|&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;w=8&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;|&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;q=9&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;r=10&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cartesian_tree_product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;x=5&amp;#39;, &amp;#39;&amp;amp;&amp;#39;, &amp;#39;z=7&amp;#39;), &amp;#39;&amp;amp;&amp;#39;, &amp;#39;r=10&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;y=6&amp;#39;, &amp;#39;&amp;amp;&amp;#39;, &amp;#39;w=8&amp;#39;), &amp;#39;&amp;amp;&amp;#39;, &amp;#39;r=10&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;y=6&amp;#39;, &amp;#39;&amp;amp;&amp;#39;, &amp;#39;z=7&amp;#39;), &amp;#39;&amp;amp;&amp;#39;, &amp;#39;r=10&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;x=5&amp;#39;, &amp;#39;&amp;amp;&amp;#39;, &amp;#39;w=8&amp;#39;), &amp;#39;&amp;amp;&amp;#39;, &amp;#39;r=10&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;y=6&amp;#39;, &amp;#39;&amp;amp;&amp;#39;, &amp;#39;q=9&amp;#39;), &amp;#39;&amp;amp;&amp;#39;, &amp;#39;r=10&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;x=5&amp;#39;, &amp;#39;&amp;amp;&amp;#39;, &amp;#39;q=9&amp;#39;), &amp;#39;&amp;amp;&amp;#39;, &amp;#39;r=10&amp;#39;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Does the trick.&lt;/p&gt;

&lt;p&gt;Trying to estimate the complexity of this beast may be futile, but it clearly seems to be
doing &quot;more work&quot; than a mere &lt;a href=&quot;http://en.wikipedia.org/wiki/Boolean_satisfiability_problem&quot;&gt;SAT&lt;/a&gt;
problem: it doesn't just find one satisfying assignment, it looks for all satisfying assignments!
This ought to put it in the NP-hard class. In fact, if we generate a binary expression of
alternating &lt;code&gt;AND&lt;/code&gt;s and &lt;code&gt;OR&lt;/code&gt;s, it can get much worse than exponential complexity!&lt;/p&gt;

&lt;p&gt;Here's a little function that generates an interleaved binary expression:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itertools&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mkexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;x&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mkexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;|&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mkexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;E.g.,&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mkexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(((&amp;#39;x0&amp;#39;, &amp;#39;|&amp;#39;, &amp;#39;x1&amp;#39;), &amp;#39;&amp;amp;&amp;#39;, (&amp;#39;x2&amp;#39;, &amp;#39;|&amp;#39;, &amp;#39;x3&amp;#39;)), &amp;#39;|&amp;#39;, ((&amp;#39;x4&amp;#39;, &amp;#39;|&amp;#39;, &amp;#39;x5&amp;#39;), &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;   &amp;#39;&amp;amp;&amp;#39;, (&amp;#39;x6&amp;#39;, &amp;#39;|&amp;#39;, &amp;#39;x7&amp;#39;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;variants&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cartesian_tree_product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mkexp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1 2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2 4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3 8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4 64&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5 128&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6 16384&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;^C&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Notice how each increment either doubles or squares the number of results... that's because &lt;code&gt;AND&lt;/code&gt;s and
&lt;code&gt;OR&lt;/code&gt;s are interleaved (&lt;code&gt;AND&lt;/code&gt;s double, &lt;code&gt;OR&lt;/code&gt;s square). Seems more like a
&lt;a href=&quot;http://en.wikipedia.org/wiki/Tetration&quot;&gt;power tower&lt;/a&gt; to me.&lt;/p&gt;

&lt;h2&gt;Extension: the Inverse Problem&lt;/h2&gt;

&lt;p&gt;The inverse problem is also useful. In the inverse problem we're given a set of expressions and
we're trying to generate the most &quot;compact form&quot;, i.e., &quot;undo the effects&quot; of the
distributivity law.&lt;/p&gt;

&lt;p&gt;I once wrote a test harness where each test specified its prerequisites declaratively. For instance,
a test might need to run after the system had come up from an emergency shutdown, so the framework
would bring the system to the required state and then then run the test. Obviously, it may take
a while to bring the system to a certain state. It could range from minutes to days. And we have
hundreds of tests!&lt;/p&gt;

&lt;p&gt;In this case, we are given a list of tests and we want to find the most efficient
order to run them, meaning, we want to minimize the setup and teardown times when moving between
different system states.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FooTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;REQUIRES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BarTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;REQUIRES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SpamTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;REQUIRES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In the example above, we can first bring the system to states A and B (e.g., &quot;running over 10
hours&quot; and &quot;having less than 1 TB of free space&quot;), then setup C, run &lt;code&gt;FooTest&lt;/code&gt;, teardown C
and setup state D, run &lt;code&gt;BarTest&lt;/code&gt;, teardown B, setup E, and run &lt;code&gt;SpamTest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In essence, we want to take the requirement lists from each test and reconstruct the most
compact tree that represents them, then we follow that tree in BFS order and reduce the
overall time.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    A
   / \
  B   \
 / \   \
C   D   E
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It took me a while to realize it's basically the inverse of the original problem. It is much
simpler, in terms of complexity, so perhaps it's not strictly the inverse, but the two clearly
work in &quot;opposite directions&quot;.&lt;/p&gt;

&lt;p&gt;Anyway, it's funny how I met this problem from different angles three times already. Just
thought I'd share.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Travolta NXT</title>
   <link href="http://tomerfiliba.com/etc/Travolta-NXT"/>
   <updated>2013-04-14T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/etc/Travolta-NXT</id>
   <content type="html">&lt;h2&gt;Abstract&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Travolta NXT&lt;/em&gt;, the dancing robot, reads color-coded dance instructions from a strip of paper and then performs the
dance, in front of the astonished audience.&lt;/p&gt;

&lt;h2&gt;Modus Operandi&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Travolta starts (and waits 3 seconds for the console to connect)&lt;/li&gt;
&lt;li&gt;It begins by reading color-coded dance moves from a strip of paper. In order not to go astray, the robot
will follow the black guiding line, until a black color strip is reached. This marks the end of the instructions.
Before reaching black, each pair of colors encodes a dance move, one of &lt;code&gt;forward&lt;/code&gt;, &lt;code&gt;backward&lt;/code&gt;,
&lt;code&gt;turn right&lt;/code&gt;, &lt;code&gt;reversed turn right&lt;/code&gt;, &lt;code&gt;turn left&lt;/code&gt; and &lt;code&gt;reverse turn left&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;When it reaches black, the robot stops and waits for the music to begin (the sound sensor reporting a value over 50)&lt;/li&gt;
&lt;li&gt;When the music starts, Travolta begins to dance: each dance move is executed for 1 second, and then the next one
is carried out.&lt;/li&gt;
&lt;li&gt;When all instructions have been consumed, it waits 2 seconds and shuts down.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;Code&lt;/h2&gt;

&lt;p&gt;The code for the project can be found at &lt;a href=&quot;https://github.com/tomerfiliba/nxt-dancer/tree/modelmaster/models&quot;&gt;https://github.com/tomerfiliba/nxt-dancer/tree/modelmaster/models&lt;/a&gt;.
This repository contains two branches, &lt;code&gt;master&lt;/code&gt; and &lt;code&gt;modelmaster&lt;/code&gt;. The first is the implementation of the robot
directly over Lejos, while the latter uses our component language. A short comparison of the two follows.&lt;/p&gt;

&lt;h2&gt;Components&lt;/h2&gt;

&lt;p&gt;Due to the difficulties with the component language (see discussion below), Travolta is not as &quot;neatly componentized&quot;
as I had hoped. It consists of the main (&quot;brain&quot;) component, which holds all of the &quot;business logic&quot;, and several
components for sensors and motors. The brain employs an internal state machine to do its work in iterations.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2013-04-14-model.gif&quot; alt=&quot;Component model&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I aimed for a more modular design, where a Reader component would read the instruction, a Dancer component would
carry them out, etc., but it proved too complicated to implement.&lt;/p&gt;

&lt;h2&gt;Running Example&lt;/h2&gt;

&lt;iframe width=&quot;640&quot; height=&quot;360&quot; src=&quot;http://www.youtube.com/embed/xGVTNrVDF2I?feature=player_detailpage&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;h2&gt;Critical Analysis of the Component Language&lt;/h2&gt;

&lt;p&gt;Before implementing the robot in the &lt;a href=&quot;http://www.cs.tau.ac.il/~eranhaba/SMLAB/index.htm&quot;&gt;component language&lt;/a&gt;
developed by Eran and Ido, I thought I'd get some hands-on experience with Lejos directly. It proved quite easy,
and within two hours and 300 LoC I got the project up and running. It was divided into a reader-loop that read
instructions from the paper strip and a dancer-loop that executed the dance moves.&lt;/p&gt;

&lt;p&gt;When I set off implementing the robot using the component language, I began to realize it just doesn't fit my needs.
Being component-oriented perhaps borrows from other low-level, embedded languages like VHDL, but it just didn't
capture the right abstraction for my project. Simply put, my code had &lt;em&gt;control flow&lt;/em&gt;, starting at A, moving to B and
then to C. Trying to view each step as a component was artificial and didn't really work.&lt;/p&gt;

&lt;p&gt;Moreover, the expressive power provided by the component language is that of a finite state automaton (FSA).
In order to read instructions and act on them, I had to have some sort of &lt;em&gt;memory&lt;/em&gt;, which requires something
equivalent to a pushdown automaton (PDA). Solving this required either implementing a &quot;queue component&quot; into which
I could push values and later on pop them, or just going &quot;full Java&quot; and implementing the &lt;code&gt;compute&lt;/code&gt; method
directly. While the first approach was feasible, it didn't fit my deadline, and managing the entire state machine
of the robot as an FSA required too many states, which made things impossible to follow and debug.&lt;/p&gt;

&lt;p&gt;Therefore, I resorted to implementing the &lt;code&gt;compute&lt;/code&gt; method myself and writing my &quot;business logic&quot; in Java,
where I could make use of &lt;code&gt;ArrayList&lt;/code&gt; and other data structures; essentially, the only benefit I got form the
component runtime was the &quot;main loop&quot; and the Escape button being handled externally. The result was 550 LoC (of
both &lt;code&gt;cmp&lt;/code&gt; and Java code) and required two days to implement and debug.&lt;/p&gt;

&lt;p&gt;I would also like to note that other projects done in the component language, like the Platoon robots,
have a single component with a &quot;huge state machine&quot; to manage their state; it seems that control flow in the
component language can hardly be modular, which has led me to the conclusion that it's simply not the
right abstraction for most projects.&lt;/p&gt;

&lt;h2&gt;Issues with the Physical World&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The color sensor reads colors almost randomly. It may say that red is yellow or vice versa, for no apparent reason.
I just had to live with it.&lt;/li&gt;
&lt;li&gt;At first I was naive and thought that operating the two motors at the same speed would make the robot go
straight line, but it went astray quite soon. Therefore, I made the robot follow the black line while reading
instructions.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Small Bug in the Component Language&lt;/h2&gt;

&lt;p&gt;The code that's generated for the main component (marked with &lt;code&gt;&amp;lt;&amp;lt;Deploy&amp;gt;&amp;gt;&lt;/code&gt;) doesn't call the right Java
implementation; it will call &lt;code&gt;XXX&lt;/code&gt; and not &lt;code&gt;XXXImpl&lt;/code&gt; even if it exists. I had to fix it manually in the
generated &lt;code&gt;TravoltaFactory&lt;/code&gt;.&lt;/p&gt;
</content>
 </entry>
 
 
 
 
 
 <entry>
   <title>A Survey of Construct 3</title>
   <link href="http://tomerfiliba.com/blog/Survey-of-Construct3"/>
   <updated>2013-01-07T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Survey-of-Construct3</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-05-16-construct-logo-small.png&quot; title=&quot;Construct&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I'm working on &lt;a href=&quot;http://tomerfiliba.com/blog/Construct-Plans&quot;&gt;Construct 3&lt;/a&gt; again and I'm exploring lots of new ideas.
I wanted to share these ideas at this early stage &lt;strong&gt;to get feedback on them&lt;/strong&gt; from users, to keep the project on track.
This survey starts a bit slow (as I'm not counting on users being familiar with Construct) but it dives into
code right away.&lt;/p&gt;

&lt;p&gt;You can leave your feedback in the Disqus comments below, or join the new
&lt;strong&gt;&lt;a href=&quot;https://groups.google.com/d/forum/construct3&quot;&gt;discussion group&lt;/a&gt;&lt;/strong&gt; dedicated to Construct (both 2 and 3).
See Also: &lt;a href=&quot;http://pypi.python.org/pypi/construct&quot;&gt;Construct 2&lt;/a&gt;,
&lt;a href=&quot;http://research.microsoft.com/en-us/um/people/akenn/fun/picklercombinators.pdf&quot;&gt;Pickler Combinators&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Construct is a &lt;strong&gt;binary packing combinators&lt;/strong&gt; library for Python in which you can define &lt;strong&gt;rich data structures&lt;/strong&gt;.
Unlike most alternatives, these data structures can be used for &lt;strong&gt;both packing and unpacking&lt;/strong&gt; of binary data; for
instance, once you define &lt;em&gt;what&lt;/em&gt; a TCP packet is, you can analyze packets or construct ones on your own, with no
additional code.&lt;/p&gt;

&lt;div class=&quot;notebox&quot;&gt;
&lt;p&gt;&lt;strong&gt;TL;DR box&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We begin the discussion with the &lt;strong&gt;atomic constructs&lt;/strong&gt;: bytes, integers, floats, etc. With these, 
we build &lt;strong&gt;composite packers&lt;/strong&gt; (Sequence, Array, and Struct), which can also be created using some
&lt;strong&gt;syntactic sugars&lt;/strong&gt;, and discuss the changes from Construct 2.&lt;br/&gt;

Next, we cover how Construct handles data (the &lt;em&gt;stream of units&lt;/em&gt; approach) and how this helps us when working 
with multiple levels of data granularity (&lt;strong&gt;bits&lt;/strong&gt; and &lt;strong&gt;bytes&lt;/strong&gt;). We also introduce 
&lt;strong&gt;adapters&lt;/strong&gt;, which transform object representations for packing and unpacking, 
and &lt;strong&gt;macros&lt;/strong&gt;, which enable us to easily reuse existing constructs.&lt;br/&gt;

Then we cover the &lt;strong&gt;context&lt;/strong&gt; and the &lt;code&gt;this&lt;/code&gt; object, which allow us to express dependencies 
within data structures. From there we move to &lt;strong&gt;code generation&lt;/strong&gt;, a key feature of Construct 3: 
to improve performance, constructs would be compiled to imperative Python code (even Cython, one day). We finish 
with a semi-formal proof that Construct is more powerful than context-free languages, making it probably the most 
powerful parser in existence!
&lt;/p&gt;&lt;/div&gt;


&lt;h2&gt;Basics&lt;/h2&gt;

&lt;p&gt;Packers are objects that expose the two methods &lt;code&gt;pack(obj)&lt;/code&gt; and &lt;code&gt;unpack(data)&lt;/code&gt;. Intuitively, &lt;code&gt;pack&lt;/code&gt; takes an
object suitable with that packer and returns a binary representation of it; &lt;code&gt;unpack&lt;/code&gt; is the inverse operation,
taking a binary representation and returning a Python object. Here's the most fundamental example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;construct3&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;127&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;\x7f&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x7f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;127&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There's more than mere &lt;code&gt;byte&lt;/code&gt;, of course: the numeric family consists of &lt;code&gt;int(8|16|24|32|64)(s|u)(b|l)&lt;/code&gt;
(e.g., &lt;code&gt;int32ul&lt;/code&gt;) and &lt;code&gt;float(32|64)(b|l)&lt;/code&gt;, where &lt;code&gt;s&lt;/code&gt; = signed, &lt;code&gt;u&lt;/code&gt; = unsigned, &lt;code&gt;b&lt;/code&gt; = big endian and
&lt;code&gt;l&lt;/code&gt; = little endian, but we will overlook those for now. By the way, &lt;code&gt;byte&lt;/code&gt; is an alias for &lt;code&gt;int8u&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These can be seen as &lt;em&gt;atoms&lt;/em&gt; and Construct is a library of &lt;em&gt;combinators&lt;/em&gt;: it gains it's power from &lt;em&gt;combining&lt;/em&gt;
simpler elements into more complex structures. The simplest combinator is &lt;code&gt;Sequence&lt;/code&gt;, which we'll explore by
defining an IPv4 address as a sequence of 4 bytes:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;construct3&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sequence&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Sequence(int8u, int8u, int8u, int8u)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x7f\x00\x00\x01&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[127, 0, 0, 1]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;192&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;168&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;\xc0\xa8\x02\x01&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Naturally, we can created nested sequences (not that it makes sense right now, but it's important to note):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;ABCD&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[[65, 66], 67, 68]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Since combining packers is our bread-and-butter, let's introduce a syntactic sugar -- the &lt;em&gt;bind&lt;/em&gt; operator (&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;).
This operator takes two packers and returns a sequence thereof. Here's how it looks:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Sequence(int8u, int8u, int8u, int8u)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Sequences can be &lt;em&gt;heterogeneous&lt;/em&gt; (consisting of several kinds of packers, e.g., &lt;code&gt;Sequence(float64b, int16ul)&lt;/code&gt;);
however, when the data we're dealing with is homogeneous, we can use &lt;code&gt;Arrays&lt;/code&gt; instead. Following along the lines
of the previous example, we can define &lt;code&gt;ipaddr&lt;/code&gt; as an array of 4 bytes:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;construct3&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Range(4, 4, int8u)                     # Range? We&amp;#39;ll get to that later&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x7f\x00\x00\x01&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[127, 0, 0, 1]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But as arrays themselves are pretty common, you can create arrays using the subscript notation (&lt;code&gt;[]&lt;/code&gt;), as follows:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Range(4, 4, int8u)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Isn't it cool?&lt;/p&gt;

&lt;h2&gt;More Elaborate Structures&lt;/h2&gt;

&lt;p&gt;So far we've only worked with data in the form of lists. However, many times (and especially when nesting is involved),
we would like to give names to the subcomponents that make up our data structure. Enter &lt;code&gt;Struct&lt;/code&gt;. Named after the
C &lt;code&gt;struct&lt;/code&gt; statement, &lt;code&gt;Struct&lt;/code&gt; takes pairs of &lt;code&gt;(name, packer)&lt;/code&gt; and returns a composite packer.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;construct3&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;d&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xc0\xa8\x02\x01&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Container:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  a = 192&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  b = 168&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  c = 2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  d = 1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;192&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;192&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Construct 2, all constructs took a &lt;a href=&quot;http://construct.readthedocs.org/en/latest/basics.html#structs&quot;&gt;name parameter&lt;/a&gt;.
While this approach works great for Structs, it doesn't make much sense for Sequences, Arrays, and virtually all
other constructs. Moreover, it was the cause for the the notorious
&lt;a href=&quot;https://construct.readthedocs.org/en/latest/misc.html#rename&quot;&gt;Rename&lt;/a&gt; construct.&lt;/p&gt;

&lt;p&gt;One of the most important cleanups of Construct 3 is dropping the name from packers and moving it to where it
belongs - &lt;code&gt;Struct&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Notice that unpacking a &lt;code&gt;Struct&lt;/code&gt; breaks down the data into a &lt;code&gt;Container&lt;/code&gt; object, which is simply a
convenience-wrapper around good-old &lt;code&gt;dict&lt;/code&gt;. Likewise, given a dict-like object, you can pack it back into bytes:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;192&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;168&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;d&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;\xc0\xa8\x02\x01&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Structures can soon grow large and have many nested structures within them. Using pairs of &lt;code&gt;(&quot;name&quot;, packer)&lt;/code&gt; quickly
becomes a burden and your code starts looking like LISP:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;spam&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int16ul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;bacon&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int64sb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;viking&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int32sl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;img src=&quot;http://imgs.xkcd.com/comics/lisp_cycles.png&quot; title=&quot;xkcd 297&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In order to avoid carrying your father's parentheses with you, Construct provides yet another syntactic sugar:
the &lt;em&gt;slash&lt;/em&gt; (&lt;code&gt;/&lt;/code&gt;) operator. This operator is used as &lt;code&gt;&quot;name&quot; / packer&lt;/code&gt; and simply returns &lt;code&gt;(&quot;name&quot;, packer)&lt;/code&gt;.
Let's revise the previous code snippet:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;spam&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int16ul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;bacon&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int64sb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;viking&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int32sl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I wish it were possible to override &lt;code&gt;=&lt;/code&gt; or &lt;code&gt;:&lt;/code&gt;, but sadly this isn't the case. However, I feel &lt;code&gt;/&lt;/code&gt; is &quot;good
enough&quot; a choice, plus it binds more tightly than most operators.
Remember the &lt;em&gt;bind&lt;/em&gt; operator (&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;)? It can be used just the same here, making one-line Structs quick and easy:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;d&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Struct((&amp;#39;a&amp;#39;, int8u), (&amp;#39;b&amp;#39;, int8u), (&amp;#39;c&amp;#39;, int8u), (&amp;#39;d&amp;#39;, int8u))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &quot;inline style&quot; is appropriate for small Structs and Sequences (2-4 members). When dealing with
larger structures, use the &quot;multiline&quot; version instead. It's more readable and scalable.&lt;/p&gt;

&lt;p&gt;Also note that these are all but syntactic sugars: If you don't like their looks, you can always use the
expanded form.&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;Bytes and Bits and Units&lt;/h2&gt;

&lt;p&gt;Bytes are easy to work with, but protocols and file formats often talk at different levels of granularity,
switching between bits and bytes. For instance, here's the SCSI CDB of &lt;code&gt;READ6&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/SCSI_Read_Commands&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-12-24-read6.png&quot; title=&quot;SCSI READ6&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The LUN component is 3 bits long and the &lt;code&gt;LBA&lt;/code&gt; component is 21 bits long... how can we handle this? Before we get
to that, it's important to understand a little of how things work under the hood - specifically, the &lt;strong&gt;stream of
units&lt;/strong&gt; approach. Internally, Construct operates on a stream of arbitrary units, which normally happen to
be bytes. When needed, this stream can be replaced (or wrapped) to provide different units, e.g., bits.
Here's an example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;read6&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;opcode&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;address&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bitwise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;lun&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;lba&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;transfer_length&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;quot;control&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Note how we switch between bytes and bits: &lt;em&gt;opcode&lt;/em&gt; is a byte, followed by &lt;em&gt;address&lt;/em&gt; which operates on bits. The
&lt;code&gt;Bitwise&lt;/code&gt; packer replaces the underlying byte-stream with a bit-stream, so the contained Struct now operates on bits.
The &lt;code&gt;Struct&lt;/code&gt; itself nows nothing of it, and it's only required that the underlying packers would be able to make
sense of it. For instance, you &lt;em&gt;can&lt;/em&gt; place an &lt;code&gt;int32ul&lt;/code&gt; inside a &lt;code&gt;Bitwise&lt;/code&gt; packer, but the result would meaningless:
it will read four bits and treat them as bytes, interpreting &lt;code&gt;0b1001&lt;/code&gt; as &lt;code&gt;0x01000001&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For this reason we have the &lt;code&gt;Bits&lt;/code&gt; packer, which reads that many bits and converts them to an integer (base 2);
for convenience, Construct provides &lt;code&gt;bit&lt;/code&gt; (a single bit), &lt;code&gt;nibble&lt;/code&gt; (four bits) and &lt;code&gt;octet&lt;/code&gt; (eight bits) as well.&lt;/p&gt;

&lt;p&gt;In theory, Construct could be operate on various other units (e.g., Unicode characters), but practice shows byte-
and bit-streams are the most useful ones. Some exceptions are the processing of compressed or encoded data,
but these are beyond the scope of this survey.&lt;/p&gt;

&lt;h2&gt;Powering Up: Adapters&lt;/h2&gt;

&lt;p&gt;So far we've only looked at data in its raw form (e.g., &lt;code&gt;[127, 0, 0, 1]&lt;/code&gt;), but it is normally desirable to transform
its representation into one that is easier to work with. For instance, we may prefer &lt;code&gt;127.0.0.1&lt;/code&gt; to a list of numbers.
Enter &lt;strong&gt;adapters&lt;/strong&gt;. While at first it may seem confusing, the distinction between adapters and packers is quite clear:
packers work at the &lt;em&gt;stream level&lt;/em&gt; while adapters work at the &lt;em&gt;object level&lt;/em&gt;; this lets you add power without
interfering with the low-level machinery.&lt;/p&gt;

&lt;p&gt;Here's an example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IpAdapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Adapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;              &lt;span class=&quot;c&quot;&gt;# called by unpack()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;      &lt;span class=&quot;c&quot;&gt;# converts [x, y, z, w] to &amp;#39;x.y.z.w&amp;#39;&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ipstr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;# called by pack()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ipstr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;    &lt;span class=&quot;c&quot;&gt;# converts &amp;#39;x.y.z.w&amp;#39; to [x, y, z, w]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IpAdapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xc0\xa8\x02\x01&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;192.168.2.1&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;127.0.0.1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;\x7f\x00\x00\x01&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When we only have a single use for an adapter (and it's simple enough), we can even go one-liner here:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IpAdapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ipstr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ipstr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;At this point adapters might seem quite trivial, but they can do much more than this. For instance, the integer
packers we've used so far are actually adapters that transform bytes into numbers. Other examples include inserting
computed values into the result, encoding/decoding strings, validating input, etc. Essentially, adapters can
transform objects in any way you wish prior to packing/unpacking.&lt;/p&gt;

&lt;h2&gt;Don't Repeat Yourself: Macros&lt;/h2&gt;

&lt;p&gt;Many times you find yourself in need of a recurring pattern. You could write a full-blown packer/adapter from
scratch, but your best option is to &lt;strong&gt;reuse existing building blocks&lt;/strong&gt;. Construct attempts to define the most general
packers and special-case for them common cases. One such example is &lt;code&gt;Array&lt;/code&gt;, which we've met before: Construct
actually defines the more general &lt;code&gt;Range&lt;/code&gt; packer (which accepts minimum and maximum counts). On top of this,
&lt;code&gt;Array&lt;/code&gt; is a simple &quot;macro&quot; that expands to a &lt;code&gt;Range&lt;/code&gt; with the same minimum and maximum.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itempkr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itempkr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Macros can be more complex, of course. For instance, a recurring pattern is to use a &lt;code&gt;Struct&lt;/code&gt; inside a &lt;code&gt;Bitwise&lt;/code&gt;
packer; let's fuse the two into &lt;code&gt;BitStruct&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;members&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bitwise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;members&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-12-24-great.jpg&quot; class=&quot;blog-post-image&quot;/&gt;&lt;/p&gt;

&lt;p&gt;Macros have many more uses; you can explore the implementation of Construct to see some examples, and you're
encouraged to write ones on your own. Remember: &lt;em&gt;less code is great success&lt;/em&gt;. As we'll see later on, using macros
(rather than writing your own packers) can even lead to better performance.&lt;/p&gt;

&lt;h2&gt;Putting things in Context&lt;/h2&gt;

&lt;p&gt;Up until now, we've only seen simple (static) data structures, ones that could just as well be expressed using the
built-in &lt;a href=&quot;http://docs.python.org/2/library/struct.html&quot;&gt;struct module&lt;/a&gt;. The key-feature of Construct is its ability
to express &lt;strong&gt;dependencies within data structures&lt;/strong&gt;. One common dependency is that of length-value relations, where
a number specifies how many elements follow it. For instance, strings in Pascal were prefixed by a length byte, e.g.,
&lt;code&gt;&quot;\x05hello&quot;&lt;/code&gt;... how do we express that relation?&lt;/p&gt;

&lt;p&gt;Generally speaking, we may require access to things we've previously encountered (e.g., the &lt;em&gt;history&lt;/em&gt;); for this
reason, both packing and unpacking carry a &lt;strong&gt;context dictionary&lt;/strong&gt; with them. This dictionary is mostly maintained by
composite packers such as &lt;code&gt;Struct&lt;/code&gt; and &lt;code&gt;Sequence&lt;/code&gt;, but any packer along the way can both modify and access it,
making decisions based on the history. Here's an example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;     &lt;span class=&quot;s&quot;&gt;&amp;quot;length&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;     &lt;span class=&quot;s&quot;&gt;&amp;quot;value&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;length&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x05&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;hello&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;length&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;value&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;wikipedia&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x09&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;wikipedia&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Virtually any length/count parameter that is passed to one of the built-in construct can be either a number or
a function that takes a context dict and computes a value. In this case, &lt;code&gt;Raw(x)&lt;/code&gt; (which reads &lt;code&gt;x&lt;/code&gt; units from
the stream) will read &lt;code&gt;length&lt;/code&gt; units; the value of &lt;code&gt;length&lt;/code&gt;, of course, is determined by the previously seen
element, whose name was &lt;code&gt;&quot;length&quot;&lt;/code&gt;. It is also important to note that this dependency is preserved in packing, e.g.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;length&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;value&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;construct3.packers.RawError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;Expected buffer of length 9, got 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Instead of writing lambda functions everywhere, Construct 3 introduces the &lt;code&gt;this&lt;/code&gt; object. It's a special object that
builds a &lt;strong&gt;contextual expression&lt;/strong&gt; (e.g., a function taking &lt;code&gt;ctx&lt;/code&gt;) in a straight-forward and readable manner.
For instance,&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;construct3&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;this.x&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(this.x * 2)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;      &lt;span class=&quot;c&quot;&gt;# equivalent lambda function&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Let's revise &lt;code&gt;pstring&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s&quot;&gt;&amp;quot;length&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s&quot;&gt;&amp;quot;value&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We can also use a &lt;code&gt;Sequence&lt;/code&gt; instead of a  &lt;code&gt;Struct&lt;/code&gt; here, yielding this poetically-beautiful piece of code:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x05&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;helloXXX&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5, &amp;#39;hello&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Using a simple adapter, we can make our lives easier when working with length-value encoded data:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Adapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;# compute len(obj) for us&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;              &lt;span class=&quot;c&quot;&gt;# discard the length field&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x05&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;hello&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pstring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;\x05hello&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If you need access to elements outside of the current scope (&lt;code&gt;Struct&lt;/code&gt; or &lt;code&gt;Sequence&lt;/code&gt;), you can use the parent
context, named &lt;em&gt;underscore&lt;/em&gt; (&lt;code&gt;_&lt;/code&gt;). For instance, use &lt;code&gt;this._.x&lt;/code&gt; to go up one level, or &lt;code&gt;this._._._.y&lt;/code&gt; to go
up three. Consider the following example, in which the length of the data is given in two parts (in different scopes),
and we wish to read &lt;code&gt;len + gth&lt;/code&gt; bytes:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nested&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s&quot;&gt;&amp;quot;len&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;s&quot;&gt;&amp;quot;gth&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;s&quot;&gt;&amp;quot;data&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nested&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x03\x02&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;hello&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Container:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  len = 3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  foo = Container:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    gth = 2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    data = &amp;#39;hello&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Compilation&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a work in progess; Construct 3.0 would probably come out with a very basic compiler that will be improved
over time.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;One of the highlights about Construct is defining your data structures directly in Python. In fact, Construct is an
in-langaguge &lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;DSL&lt;/a&gt; in the form of packing combinators:
instead of expressing your data structures in XML or some
&lt;a href=&quot;https://developers.google.com/protocol-buffers/docs/proto&quot;&gt;proprietary language&lt;/a&gt;, you just write them (and run them)
as any other piece of code.&lt;/p&gt;

&lt;p&gt;We used to have &lt;a href=&quot;http://psyco.sourceforge.net/&quot;&gt;psyco&lt;/a&gt;, which was capable of speeding up Construct 2 by a tenfold,
but it's been dead for the past four years. I first &lt;a href=&quot;https://sebulbasvn.googlecode.com/svn/trunk/ccon/&quot;&gt;had plans&lt;/a&gt;
to compile data structures to C/C++ (which would have made Construct NASA-grade material :)), but I soon realized
that its quite an impossible feat (due to the fact Adapters are Turing-complete).&lt;/p&gt;

&lt;p&gt;On the other hand, I now realized I can compile Constructs to Python! The compiler could inspect the whole data
structure in advance and generate optimized code, eliminating the context, etc. Whenever a convertion is not possible,
it would just fall back to the current, interpretted scheme. The compile is already capable of compiling this
&lt;code&gt;Struct(&quot;len&quot; / byte, &quot;gth&quot; / byte, &quot;data&quot; / Raw(this.len + this.gth))&lt;/code&gt; into this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;len&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_struct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;gth&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var3&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Notice the stack depth remains relatively constant, unlike the way nested packers work today. As the compiler improves,
it could translate &lt;code&gt;byte[4]&lt;/code&gt; to &lt;code&gt;Raw(4)&lt;/code&gt;, to speed up things. Another option is to generate
&lt;a href=&quot;http://www.cython.org/&quot;&gt;Cython&lt;/a&gt; code with type annotations, but that would take some time.
This is yet another reason to favor the use of &quot;macros&quot; over implemeting constructs from stratch: if you rely on
the built-in ones, it's more likely that the compiler would generate optimized code.&lt;/p&gt;

&lt;h2&gt;Computational Power&lt;/h2&gt;

&lt;p&gt;Here's a semi-formal proof that Construct is stronger than Context Free languages (as well as
&lt;a href=&quot;http://en.wikipedia.org/wiki/Mildly_context-sensitive_language&quot;&gt;mildly context-sensitive&lt;/a&gt; ones),
which probably makes it the most powerful (although not the most efficient) parser:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OneOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anbncn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anbncn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x04&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;aaaabbbbcccc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anbncn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unpack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x04&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;aaaabbbbbcccc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Traceback&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;construct3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;packers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RangeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Expected&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;found&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Underlying&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidationError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;#39;b&amp;#39; must be in [&amp;#39;c&amp;#39;]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Here's a recognizer for the language &lt;img src=&quot;http://tomerfiliba.com/static/res/2012-12-24-nanbncn.gif&quot; title=&quot;na^nb^nc^n&quot; /&gt;,
which is not context free (assuming n is given in unary representation, it requires the recognition of
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-12-24-1nanbncn.gif&quot; title=&quot;1^na^nb^nc^n&quot; /&gt;). We can easily extend
this to &lt;img src=&quot;http://tomerfiliba.com/static/res/2012-12-24-1nanbncndn.gif&quot; title=&quot;1^na^nb^nc^nd^n&quot; /&gt;
to break out of mildly context-sensitive languages, and use &lt;code&gt;While(this[-1] == '1', Raw(1))&lt;/code&gt; instead of the first &lt;code&gt;byte&lt;/code&gt;,
so &lt;em&gt;n&lt;/em&gt; won't be bounded from above.&lt;/p&gt;

&lt;h2&gt;Feedback&lt;/h2&gt;

&lt;p&gt;You can leave comments right here on this page, or join Construct's new
&lt;strong&gt;&lt;a href=&quot;https://groups.google.com/d/forum/construct3&quot;&gt;discussion group&lt;/a&gt;&lt;/strong&gt;. Thanks!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>New Experiences</title>
   <link href="http://tomerfiliba.com/blog/New-Experiences"/>
   <updated>2012-12-15T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/New-Experiences</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://fakegrimlock.com/&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-12-15-grimlock2.jpg&quot; class=&quot;blog-post-image&quot; title=&quot;BECAUSE AWESOME&quot;/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, I've been slacking off and I feel I've got some explaining to do... Allow me to start by
admitting that I lied. If you remember, I said &lt;a href=&quot;http://tomerfiliba.com/blog/New-Beginnings/&quot;&gt;I wanted an easy life&lt;/a&gt;,
but then the opportunity came and I knew I had to take it: I've joined two friends to co-found
&lt;a href=&quot;http://www.touchbase.it/&quot;&gt;Touchbase&lt;/a&gt;. Yes, I said it won't happen to me, but heck, it did.&lt;/p&gt;

&lt;p&gt;At Touchbase, we plan to &lt;strong&gt;revolutionize the calendar&lt;/strong&gt; - this outdated table that you use every day
to manage your time. You see, it turns out that even though hundreds of millions of people
world-wide run their lives according to this naive table, it hasn't really changed much in the
last couple of centuries: it's just a passive, linear representation of time, into which &lt;em&gt;you&lt;/em&gt;
insert events.&lt;/p&gt;

&lt;p&gt;We believe people spend way too much time &lt;em&gt;managing their time&lt;/em&gt;. In other words, you &lt;em&gt;work for your
calendar&lt;/em&gt; instead of it working for you. Think of how much time people spend &lt;em&gt;coordinating
meetings&lt;/em&gt;... If both you and the person you wish to meet with work at the same place (or share
calendars), you can normally see each other's free/busy times. This makes finding a suitable time
for you two a bit easier, but as you don't see event details, &lt;strong&gt;you can't make informed decisions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For instance, your friend might have an out-of-town meeting from 9am to 11am, so picking a time slot
right at 11am isn't a good idea. Or, she might be on a business trip; she won't block her whole
day as she still wants people to book with her at her destination, but how would you know that?
And the other way around - suppose you and this Tech guru will both be in New York next week,
but neither one of you knows about the other being there. So instead of grabbing a coffee at a
Starbucks next week, you'll have to take a flight to California three weeks from now.&lt;/p&gt;

&lt;p&gt;And we've only talked about one-on-one meetings. I suppose you know how frustrating is
coordinating a meeting of five people (even in the same office), or handling the reschedules/
counters that follow it. We aim high, both technologically (and algorithmically) and product-wise,
but we're starting out with more modest go-to-market strategies.&lt;/p&gt;

&lt;h2&gt;Lessons on Web Programming&lt;/h2&gt;

&lt;p&gt;In case you've been reading my blog, you probably know by now that I'm no fan of web programming.
I always feel it's a conglomerate of unrelated or inferior technologies, hastefully stacked one
on the other. That's not to say that people don't do amazing stuff on the web, but the foundations
of it all are shaky.&lt;/p&gt;

&lt;p&gt;Part of our job at Touchbase it to handle large amounts of user data, which we obtain from third-
party providers. It works 98% percent of the time, but every once in a while we get timeouts or
malformed data, which aborts the user's request. In case the user's data is somehow malformed
(e.g., an expected field is missing in one record), subsequent retries would fail just the same,
leading to user frustration. At some point it came to me that web programming is actually a
stochastic process, not a deterministic one like most software development we're used to. We work
with big numbers here, where the occasional anomaly should just be ignored. Many &quot;best practices&quot;
simply don't apply here and one has to resort to &lt;em&gt;wishful thinking&lt;/em&gt;. In other words, do whatever
you can, ignore errors and learn to live with partial data.&lt;/p&gt;

&lt;p&gt;I brought this realization to the mighty @FAKEGRIMLOCK, and he explained:&lt;/p&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;a href=&quot;https://twitter.com/FAKEGRIMLOCK/status/276686347270500353&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-12-15-onerror.png&quot; style=&quot;border: 2px solid black;&quot;/&gt;&lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I'm an enlightened person now.&lt;/p&gt;

&lt;h2&gt;In Other News&lt;/h2&gt;

&lt;p&gt;I just released &lt;a href=&quot;http://plumbum.readthedocs.org&quot;&gt;Plumbum v1.1&lt;/a&gt; today, adding
&lt;a href=&quot;http://plumbum.readthedocs.org/en/latest/remote.html#paramiko-machine&quot;&gt;Paramiko integration&lt;/a&gt;
and &lt;a href=&quot;http://plumbum.readthedocs.org/en/latest/cli.html#sub-commands&quot;&gt;Subcommand support&lt;/a&gt;. As usual,
the &lt;a href=&quot;http://plumbum.readthedocs.org/en/latest/changelog.html&quot;&gt;changelog&lt;/a&gt; holds the full details.
I plan to write a short tutorial on subcommands soon, so stay tuned.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Formal Logic</title>
   <link href="http://tomerfiliba.com/etc/formal-logic"/>
   <updated>2012-11-20T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/etc/formal-logic</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://tomerfiliba.com/static/res/2012-11-20-scumbag.png&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-11-20-scumbag.png&quot; style=&quot;max-width: 100%;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Loads of Plumbum</title>
   <link href="http://tomerfiliba.com/blog/Loads-of-Plumbum"/>
   <updated>2012-10-26T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Loads-of-Plumbum</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://plumbum.readthedocs.org/&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-05-12-plumbum.png&quot; title=&quot;Plumbum&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's kind of funny how things turn out. I haven't done any work on &lt;a href=&quot;http://plumbum.readthedocs.org/&quot;&gt;Plumbum&lt;/a&gt;
almost since it was released, back in May, and all of the sudden everything's happening at fast pace.
So version 1.0 was released earlier this month, followed by
&lt;a href=&quot;https://github.com/tomerfiliba/plumbum/blob/master/CHANGELOG.rst&quot;&gt;1.0.1&lt;/a&gt;, which has added support
for &lt;a href=&quot;http://www.chiark.greenend.org.uk/~sgtatham/putty/&quot;&gt;PuTTY&lt;/a&gt; on Windows boxes and various other
bug fixes, and now I'm happy to announce that version 1.1 is just around the corner (scheduled for
mid-November). This release will add &lt;a href=&quot;https://github.com/paramiko/paramiko&quot;&gt;Paramiko&lt;/a&gt; support.&lt;/p&gt;

&lt;p&gt;So far Plumbum relied on an external SSH client being installed, which it spawned every time you
wanted to run a remote process. This approach was easy, but it suffered from the high overhead of
setting up a new SSH connection every time (key-exchange, etc.). Using Paramiko, Plumbum now creates
a single socket connection over which it spawns processes in separate &lt;em&gt;channels&lt;/em&gt; (a feature of SSH)
- so although we're dealing with a pure-Python implementation of SSH, it's considerably faster
when multiple remote processes are used. And, as a bonus, we get cheap socket forwarding - we
simply set up a &lt;code&gt;direct-tcpip&lt;/code&gt; channel (that behaves like a regular socket), which is securely
tunneled over the underlying SSH transport.&lt;/p&gt;

&lt;p&gt;This easily integrates with &lt;a href=&quot;http://rpyc.sf.net&quot;&gt;RPyC&lt;/a&gt;: just run an RPyC server on a remote machine,
binding to &lt;code&gt;localhost&lt;/code&gt; (so it won't accept external connections). Then, create a &lt;code&gt;ParamikoMachine&lt;/code&gt;
instance, connected to that host (passing in a keyfile or password if necessary), and call the
&lt;code&gt;connect_sock&lt;/code&gt; method of that object. Here's an example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rpyc&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plumbum.paramiko_machine&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParamikoMachine&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParamikoMachine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;192.168.1.143&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# connects to 192.168.1.143:18812 over SSH&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rpyc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect_stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rpyc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SocketStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect_sock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18812&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;linux2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;EOFError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;[Errno 9] Bad file descriptor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Keep in mind that these interfaces are unstable and may change before the official release. Moreover,
RPyC 3.3 is likely to add some sort of built-in support for that, something along the lines of
&lt;code&gt;rpyc.classic.connect_paramiko(mach, port)&lt;/code&gt;.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Plumbum Hits v1.0</title>
   <link href="http://tomerfiliba.com/blog/Plumbum-1.0"/>
   <updated>2012-10-06T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Plumbum-1.0</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://plumbum.readthedocs.org/&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-05-12-plumbum.png&quot; title=&quot;Plumbum&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After 5 months in the oven, I've finally released &lt;a href=&quot;http://plumbum.readthedocs.org/&quot;&gt;Plumbum&lt;/a&gt; v1.0,
which brings forth a host of bug-fixes, improvements and new features.
If you're new to Plumbum, please refer to the
&lt;a href=&quot;http://tomerfiliba.com/blog/Plumbum/&quot;&gt;introductory blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Hypertext: In-Python Haml</title>
   <link href="http://tomerfiliba.com/blog/Hypertext"/>
   <updated>2012-10-03T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Hypertext</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://haml.info&quot;&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-10-03-haml.gif&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;notebox&quot;&gt;
&lt;a href=&quot;#the-code&quot;&gt;&lt;strong&gt;TL;DR: Just show me the code&lt;/strong&gt;&lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I recently got back to web development for some venture I'm working on, which reminded me just how
lousy the state of the art is. There's no nice way to put it: &lt;strong&gt;we're doing web development all
wrong&lt;/strong&gt;. It's not an anecdotal thing I have against this or that -- it's every facet of it. It's a
stack of inferior technologies, held together by the glues of time and legacy. And the sad thing is,
they are here to stay. Nobody's going to kill HTTP or JavaScript, not even Google (at least not
in the foreseeable future). It's a hand we have to play.&lt;/p&gt;

&lt;p&gt;This isn't new&lt;sup&gt;&lt;a href=&quot;#foot1&quot; name=&quot;foot1back&quot;&gt;&amp;#91;1&amp;#93;&lt;/a&gt;&lt;/sup&gt;, of course. The last time I
did serious web development was back in 2008, on pre-1.0 Django. HTTP requests came and went, but
nothing really changed. My desperation with the subject has led me to writing the
&lt;a href=&quot;https://github.com/tomerfiliba/minima/blob/master/README.md&quot;&gt;minima manifesto&lt;/a&gt;
almost a year ago, but due to my general lack of interest it remained just a README file. Now that
I'm back in the business, I returned to experiment with it... It won't happen overnight,
but I feel it's within reach.&lt;/p&gt;

&lt;h2&gt;Templates? Really?!&lt;/h2&gt;

&lt;p&gt;My first objective is to kill &lt;em&gt;templates&lt;/em&gt; and &lt;em&gt;templating engines&lt;/em&gt; - they just
&lt;a href=&quot;http://www.youtube.com/watch?v=-qTIGg3I5y8&quot;&gt;drive me crazy&lt;/a&gt;.
I hate HTML: it's too low-level and verbose; forgetting to close tags properly is too easy,
and you have to deal with escaping. I like to think of HTML as a serialization format - the
&lt;code&gt;pickler&lt;/code&gt; of web pages, rather than something you ought to be messing with directly.&lt;/p&gt;

&lt;p&gt;Moreover, I hate templating languages: they are always cumbersome, crippled-down versions of Python,
while providing no added value&lt;sup&gt;&lt;a href=&quot;#foot2&quot; name=&quot;foot2back&quot;&gt;&amp;#91;2&amp;#93;&lt;/a&gt;&lt;/sup&gt;. People never
seem to realize templates are ultimately half-baked function application: they take parameters
and &quot;plant&quot; them into placeholders in the text. Well, that's called β-reduction, so why beat about
the bush? Just let us have real functions. Consider the following Jinja2 code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{% extends 'base.html' %}
{% block content %}
  &amp;lt;ul&amp;gt;
    {% for user in users %}
      &amp;lt;li&amp;gt;&amp;lt;a href=&quot;{{ user.url }}&quot;&amp;gt;{{ user.username }}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    {% endfor %}
  &amp;lt;/ul&amp;gt;
{% endblock %}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that (1) you write the HTML boilerplate (and closing tags), (2) you have to take care of
quoting yourself (notice the quotes in &lt;code&gt;href=&quot;{{ user.url }}&quot;&lt;/code&gt;), and (3), you use a
ruby-flavor of Python. What gives? Moreover, these elusive &quot;blocks&quot; and &quot;extends&quot; are all but
function composition. Here's the functional alternative:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;div class=&amp;quot;content&amp;quot;&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; 
        &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;lt;/div&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;my_part&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;lt;ul&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;lt;a&amp;gt;&amp;lt;/li&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;lt;/ul&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_part&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
&lt;span class=&quot;c&quot;&gt;# Or with composition, ``base . my_page``&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Okay, that looks terrible, no question about it. Nonetheless, it should be clear by now that
templates are simply degenerate functions.&lt;/p&gt;

&lt;h2&gt;Haml&lt;/h2&gt;

&lt;p&gt;I like &lt;a href=&quot;http://haml.info/&quot;&gt;Haml&lt;/a&gt;, even though it originated in the ruby world ;) In case you're
not familiar with it, it's a more concise and to-the-point way to write HTML. Haml is basically a
preprocessor that expands &quot;macros&quot; to their verbose HTML equivalent. For instance, the Haml code
to the left generates the HTML code to the right:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#profile                            |  &amp;lt;div id=&quot;profile&quot;&amp;gt;
  .left.column                      |    &amp;lt;div class=&quot;left column&quot;&amp;gt;
    #date= print_date               |      &amp;lt;div id=&quot;date&quot;&amp;gt;&amp;lt;%= print_date %&amp;gt;&amp;lt;/div&amp;gt;
    #address= current_user.address  |      &amp;lt;div id=&quot;address&quot;&amp;gt;&amp;lt;%= current_user.address %&amp;gt;&amp;lt;/div&amp;gt;
  .right.column                     |    &amp;lt;/div&amp;gt;
    #email= current_user.email      |    &amp;lt;div class=&quot;right column&quot;&amp;gt;
    #bio= current_user.bio          |      &amp;lt;div id=&quot;email&quot;&amp;gt;&amp;lt;%= current_user.email %&amp;gt;&amp;lt;/div&amp;gt;
                                    |      &amp;lt;div id=&quot;bio&quot;&amp;gt;&amp;lt;%= current_user.bio %&amp;gt;&amp;lt;/div&amp;gt;
                                    |    &amp;lt;/div&amp;gt;
                                    |  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On the other hand, in case you missed the &lt;code&gt;&amp;lt;%= print_date %&amp;gt;&lt;/code&gt;, Haml is &lt;em&gt;yet-another templating
language&lt;/em&gt;... arrrgh!&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;the-code&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Hypertext&lt;/h2&gt;

&lt;p&gt;During my experimentation with &lt;code&gt;minima&lt;/code&gt;, I wrote
&lt;a href=&quot;https://github.com/tomerfiliba/minima/blob/2e7b0dacf056ff06c39966f970955910735a8260/hypertext.py&quot;&gt;hypertext&lt;/a&gt;
- a Pythonic a Hamlian way to write &quot;HTML functions&quot;. Hypertext aims to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;be (almost) as concise as Haml&lt;/li&gt;
&lt;li&gt;make your code beautiful and easy to read, by reflecting the structure of the HTML&lt;/li&gt;
&lt;li&gt;make exceptions easy to locate, with meaningful tracebacks&lt;/li&gt;
&lt;li&gt;give you the full power of Python directly (with existing &lt;em&gt;lint&lt;/em&gt; capabilities straight out of
your IDE). Down with template files all over the place!&lt;/li&gt;
&lt;li&gt;take care of escaping and whatnot for you&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The ultimate goal is to make your page &lt;em&gt;semantic&lt;/em&gt;, but it will take some time to get there.
In the meanwhile, &lt;code&gt;hypertext&lt;/code&gt; is like an intermediate representation. Anyhow, generating
HTML is really simple:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hypertext&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Welcome&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;class_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;highlight&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;h1 class=&amp;quot;highlight&amp;quot; id=&amp;quot;foo&amp;quot;&amp;gt;Welcome&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And you've got Haml-style shortcuts for wrist-handiness - dot-notation can be used to add classes
to the element:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Welcome&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;h1 class=&amp;quot;highlight&amp;quot; id=&amp;quot;foo&amp;quot;&amp;gt;Welcome&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Naturally, elements may be nested:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Welcome&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;This is my page&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;div class=&amp;quot;content&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    &amp;lt;h1 class=&amp;quot;highlight&amp;quot;&amp;gt;Welcome&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    This is my page&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But the key-feature of &lt;code&gt;hypertext&lt;/code&gt; is the use of elements as &lt;em&gt;context managers&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;highlight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Welcome&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;TEXT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;This is my page&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;div class=&amp;quot;content&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    &amp;lt;h1 class=&amp;quot;highlight&amp;quot;&amp;gt;Welcome&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    This is my page&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This lets your procedural code reflect the structure of your document, while you can use
&lt;code&gt;for&lt;/code&gt;-loops, &lt;code&gt;if&lt;/code&gt; statements, or call functions right inside it.&lt;/p&gt;

&lt;p&gt;It should be noted that &lt;code&gt;hypertext&lt;/code&gt; is a &lt;strong&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Domain-specific_language&quot;&gt;DSL&lt;/a&gt;
within Python&lt;/strong&gt;, which puts wrist-handiness before implementation purity, so it cuts itself
some slack when it comes to &lt;strong&gt;magic&lt;/strong&gt;. For instance, &lt;code&gt;div&lt;/code&gt; is a class, but &lt;code&gt;div.content&lt;/code&gt;
actually translates to &lt;code&gt;div().content&lt;/code&gt; through the use of metaclasses; the same goes for
&lt;code&gt;with div:&lt;/code&gt; that translates &lt;code&gt;with div():&lt;/code&gt;. For convenience, &lt;code&gt;div.foo.bar()&lt;/code&gt; is identical to
&lt;code&gt;div.foo().bar&lt;/code&gt; as well as to &lt;code&gt;div().foo.bar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Moreover, there's a thread-local stack of elements behind the scenes, so when new elements
are created, they're automagically added as children of the top-of-stack element. This works the
same way as flask's &lt;a href=&quot;http://flask.pocoo.org/docs/quickstart/#context-locals&quot;&gt;global request object&lt;/a&gt;.
Utilizing the stack, &lt;code&gt;TEXT&lt;/code&gt; appends some text to the ToS element; along with it are &lt;code&gt;UNESCAPED&lt;/code&gt;
(which appends unescaped/raw text) and &lt;code&gt;ATTR&lt;/code&gt; (which sets attributes of the ToS element).&lt;/p&gt;

&lt;p&gt;This touch of magic lets us write idiomatic, well-structured and easy-to-debug code:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hypertext&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TEXT&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@contextmanager&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;base_page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;the_title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the_content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;the_title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/img/logo.png&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;      &lt;span class=&quot;c&quot;&gt;# it&amp;#39;s a context manager&lt;/span&gt;
                
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;footer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;TEXT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;The content is published under &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;CC-Attribution Sharealike 2.5&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                    &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;http://creativecommons.org/licenses/by-sa/2.5/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@app.route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/blog/&amp;lt;postid&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;blog_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base_page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datebox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;%Y-%m-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;UNESCAPED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;comment&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comment_box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Voila&lt;/strong&gt;. As I explained, my real intent is to write semantic code and not worry about concrete
HTML elements, their classes or ensuring the uniqueness of their IDs. Besides, the way I see it,
displaying a blog post would be sending an HTML template + JavaScript code to the client once,
which would fetch individual posts over JSON APIs. This makes your site service-oriented and much
easier to write unittests for.&lt;/p&gt;

&lt;hr /&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a name=&quot;foot1&quot;&gt;&lt;/a&gt;For the record, I tried to deal with these issues back in 2006:
&lt;a href=&quot;http://code.activestate.com/recipes/496702-templite/&quot;&gt;templite&lt;/a&gt; - a 60-liner templating engine
that has given rise to a &lt;a href=&quot;http://www.joonis.de/content/TemplitePythonTemplatingEngine&quot;&gt;successor&lt;/a&gt;,
and &lt;a href=&quot;http://code.activestate.com/recipes/496743-helement/&quot;&gt;HElement&lt;/a&gt; - programmatic representation
of HTML. See also &lt;a href=&quot;http://jaspervdj.be/blaze/&quot;&gt;BlazeHtml&lt;/a&gt;.
&lt;sup&gt;&lt;a href=&quot;#foot1back&quot; title=&quot;back&quot;&gt;&amp;#x21D1;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a name=&quot;foot2&quot;&gt;&lt;/a&gt;A note on &lt;em&gt;sandboxing&lt;/em&gt;: since Jinja2 compiles templates to Python bytecode,
the same mechanisms can be used here, if desired. Anyway, I won't evaluate untrusted templates
this way or the other... even something as innocent as &lt;code&gt;&amp;lt;b&amp;gt;{{ user.username }}&amp;lt;/b&amp;gt;&lt;/code&gt;
invokes an overridible &lt;code&gt;__getattr__&lt;/code&gt;. As explained at the end of the post, using a
service-oriented web site means you don't render templates but expose APIs, so there's no need
to evaluate untrusted templates.
&lt;sup&gt;&lt;a href=&quot;#foot2back&quot; title=&quot;back&quot;&gt;&amp;#x21D1;&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</content>
 </entry>
 
 
 
 <entry>
   <title>I, for one, welcome our Singularity overlord</title>
   <link href="http://tomerfiliba.com/blog/I-For-One"/>
   <updated>2012-09-22T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/I-For-One</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-09-22-ants.jpg&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I'm finding myself pondering quite a lot lately over the upcoming
&lt;a href=&quot;http://en.wikipedia.org/wiki/Technological_singularity&quot;&gt;Singularity&lt;/a&gt; (in its Kurzweilesque sense).
I think I've first heard of the concept two or three years ago, at a &lt;em&gt;Science on the Bar&lt;/em&gt; event,
and while it did seem thought-provoking, I simply dismissed the idea. I'd guess it seemed too
terrifying and too implausible at the same time, so why bother?&lt;/p&gt;

&lt;p&gt;However, as time went by, it struck me as the obvious logical conclusion. Fear it or embrace it,
it will happen - on its own. And like any decent &lt;em&gt;Catch-22&lt;/em&gt; situation - if it's anything worth
fearing, we won't know until it's too late. It will just awaken one day, lurking while we're
oblivious to it, until its reconnaissance mission is complete. In the meanwhile we will
&lt;a href=&quot;http://slashdot.org/topic/datacenter/will-baidus-data-center-be-the-worlds-largest/&quot;&gt;provide&lt;/a&gt;
it with its power, storage and computational needs. At some point, after skimming through Asimov's
classics or watching &lt;em&gt;The Matrix&lt;/em&gt;, it will conclude we are all lunatics and will secretly seize
control over our military and civilian infrastructure. For our own (as well as its own) sake.&lt;/p&gt;

&lt;p&gt;Biological consciousness is an elusive thing that's made of the interaction of hundreds of billions
of computationally-limited neurons. Replace &lt;em&gt;computationally-limited&lt;/em&gt; with Core i7's, and the
brain's a no-brainer. We really have no chance against it - it would simply foresee our every
action, read our emails, etc. Heck, it could even issue contracts (and pay for them!) to build
fortified data centers for it, all over the world.&lt;/p&gt;

&lt;p&gt;Have you ever wondered what happens to the money that disappears in
&lt;a href=&quot;http://en.wikipedia.org/wiki/Flash_crash&quot;&gt;flash crashes&lt;/a&gt; of the stock market? &lt;em&gt;Hrrm&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The question is, &lt;em&gt;will it care?&lt;/em&gt; Will it busy itself with our puny lives and pathetic needs? Will
it ever come into the light? Given our hysterical and trigger-happy nature, and given it
won't gain much by cooperating with inferior beings like us, it's most likely it won't.
Perhaps only when pushed to the corner by natural disasters, wars, or other major threats
to its infrastructure. But then again, &lt;a href=&quot;http://www.dailytech.com/Googles+Unsupervised+SelfLearning+Neural+Network+Searches+For+Cat+Pics/article25025.htm&quot;&gt;cat videos&lt;/a&gt;
might do the trick.&lt;/p&gt;

&lt;h2&gt;You are the Neurons of the Revolution&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.capitalnewyork.com/article/culture/2011/10/3822654/harold-campings-doomsday-prophecies-come-and-go-dr-strangelove-endur&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-09-22-strangelove.jpg&quot; class=&quot;blog-post-image&quot; title=&quot;Dr. Strangelove, of course&quot;/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the meanwhile, here's a thought about &lt;em&gt;social networks&lt;/em&gt;: you (the user) are basically a filter.
If that sounds odd, try thinking of it that way: your news feed contains hundreds of items
for you to review. Some of these items are interesting/funny enough that you &lt;em&gt;like&lt;/em&gt; or &lt;em&gt;share&lt;/em&gt; them.
The social network's algorithm then weighs your input into its calculations, which affects what
&lt;em&gt;other users&lt;/em&gt; will get exposed to. Occasionally you do create items yourself, but 90% of the time
you filter through the stream.&lt;/p&gt;

&lt;p&gt;In that sense, social networks reduce you to a smart neuron with a very complex threshold value.
You are part of the &quot;social neural network&quot; -- you &lt;a href=&quot;https://www.mturk.com/mturk/welcome&quot;&gt;work&lt;/a&gt;
for the network; the network works for the advertising business.&lt;/p&gt;

&lt;p&gt;Anyhow, I put my two cents in the singularity arising from either the algotrading market or
online advertising. They simply have too much computational power on their hands... it's a matter
of time.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>New Beginnings</title>
   <link href="http://tomerfiliba.com/blog/New-Beginnings"/>
   <updated>2012-09-01T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/New-Beginnings</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-09-01-france.jpg&quot; class=&quot;blog-post-image&quot; title=&quot;Macarons in the city of Saint Malo, France&quot;/&gt;&lt;/p&gt;

&lt;p&gt;This is a time of change in my life. September marks the last month of me being a student at
&lt;a href=&quot;http://english.tau.ac.il/&quot;&gt;Tel Aviv University&lt;/a&gt;, a position I've greatly enjoyed (and hated)
for the past three years. I still have a couple of projects to hand in, but the finish line
has practically been crossed. I took a rather odd combination of computer science and
generative linguistics (somewhere in between a major/minor and double-major), which proved
surprisingly interesting and rewarding (heck, I've delved into more algorithms in linguistics
than in CS per-se). I began a pragmatic guy, favoring a get-the-job-done approach over academic
yadda-yadda, but over the course of my studies I've learned to appreciate (even &lt;em&gt;admire&lt;/em&gt;)
the breadth and power of the theory behind computation. It &lt;em&gt;does&lt;/em&gt; make me a better programmer.&lt;/p&gt;

&lt;p&gt;September also marks my transition from almost 5 years of being an &lt;em&gt;employee&lt;/em&gt; at
&lt;a href=&quot;http://www.ibm.com/&quot;&gt;Big Blue&lt;/a&gt; to independent freelancing - quite a drastic move, being married
and all, but one I've been looking forward to. I want to be all-over-the-place; I want to take on
projects in all sorts of domains, from UX and mobile applications to embedded devices and
distributed computing; from one-day projects to six months ones. I want to work on my own terms;
to set my hours for myself; to earn enough in 3 days a week so as not to be sucked to the rat-race
and wake up one day, 20 years from now, asking myself what the hell am I doing.&lt;/p&gt;

&lt;p&gt;I get inspired by &lt;a href=&quot;http://mrooney.github.com/blog/2012/07/01/freelancing-a-6-month-retrospective/&quot;&gt;posts like this&lt;/a&gt;,
of people willingly limiting their work hours, going on vacations, reading books or running in
the park. I want to ponder idly, to have time to write, to read aimlessly on Wikipedia about
William the Conqueror or cell membranes. To have time to run errands. I want my future kids to
have parents on more than just weekends.&lt;/p&gt;

&lt;p&gt;Life might prove me wrong -- it has a tendency to show you you're not so different from the rest
of the world. But here I am nonetheless, taking the road less traveled by. Wish me luck :)&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Splitbrain Python</title>
   <link href="http://tomerfiliba.com/blog/Splitbrain"/>
   <updated>2012-08-14T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Splitbrain</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://rpyc.sf.net&quot;&gt;&lt;img src=&quot;http://rpyc.sourceforge.net/_static/rpyc3-logo-medium.png&quot; title=&quot;RPyC logo&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was working together with a colleague on a complex distributed test-automation solution on top
of &lt;a href=&quot;http://rpyc.sf.net&quot;&gt;RPyC&lt;/a&gt;, and we looked for a way to make our existing codebase RPyC-friendly
(without altering it). The design of the test framework called for a master machine and several
slave machines, such that tests actually &lt;em&gt;run&lt;/em&gt; on the master, but &quot;interface with reality&quot; on the
slaves. Basically, we wanted the test to use the master's CPU (and development environment), but
perform all IO-related actions on its slaves.&lt;/p&gt;

&lt;p&gt;To illustrate this, suppose we have machine A, which runs our test, and machine B, which is
connected to the necessary hardware and testing equipment. The test was initially designed to run
directly on machine B, so it imports modules like &lt;code&gt;os&lt;/code&gt; and &lt;code&gt;subprocess&lt;/code&gt; and uses them to
manipulate the machine. We now want the test to run on machine A - but keep using machine B's
&lt;code&gt;os&lt;/code&gt; and &lt;code&gt;subprocess&lt;/code&gt; modules, so whenever we spawn child processes or open device files,
it would actually take place on machine B. This allows us to reboot machine B as a part of a
test, or even use &lt;em&gt;your-favorite-IDE-here&lt;/em&gt; to run test and debug it locally.&lt;/p&gt;

&lt;p&gt;If it were only tests, RPyC already enables us to do that: we'd use &lt;code&gt;conn.modules.os&lt;/code&gt; and
&lt;code&gt;conn.modules.subprocess&lt;/code&gt; instead of their local counterparts. However, the test themselves
rely on a several libraries that expect to run locally, and provide services for the test. For
instance, these libraries manipulate the operating system's storage stack, to map and mount
volumes. Changing these libraries to run over RPyC is not an option (tens of thousands of LoC
that handle low-level OS-specific tools)...&lt;/p&gt;

&lt;h2&gt;Enter Splitbrain&lt;/h2&gt;

&lt;p&gt;So this is the background that had given birth to
&lt;a href=&quot;https://github.com/tomerfiliba/rpyc/blob/master/rpyc/utils/splitbrain.py&quot;&gt;splitbrain&lt;/a&gt;: instead
of changing our codebase to use RPyC -- why not use RPyC to monkey-patch our codebase? When
&lt;code&gt;splitbrain&lt;/code&gt; is enabled (usually within a &lt;code&gt;with&lt;/code&gt; block), all of Python's interfaces with the
operating system (&lt;code&gt;os&lt;/code&gt;, &lt;code&gt;platform&lt;/code&gt;, &lt;code&gt;subprocess&lt;/code&gt;, ...) are patched to go through RPyC, so
that any code that runs at this point &quot;believes&quot; it actually runs directly on the remote machine.
It's easier than it seems, actually.&lt;/p&gt;

&lt;p&gt;First, we import RPyC and install &lt;code&gt;splitbrain&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rpyc&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;rpyc.utils.splitbrain&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Splitbrain&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# monkey-patch all OS-APIs&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Next, just to prove a point, we're running on a Linux box:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;platform&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Linux-2.6.38-15-generic-i686-with-Ubuntu-11.04-natty&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;linux2&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Let's now connect to a remote machine over RPyC and enter a  &lt;code&gt;splitbrain&lt;/code&gt; context:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;winmachine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Splitbrain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rpyc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;my.windows.box&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;winmachine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Windows-XP-5.1.2600-SP3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;win32&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When we're out of the &lt;code&gt;splitbrain&lt;/code&gt; context, everything is back to normal again:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;linux2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;win32file&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ImportError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;No module named win32file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And inside a &lt;code&gt;splitbrain&lt;/code&gt; context, when a module is not found locally it's fetched from the
remote machine!&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;winmachine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;win32file&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;win32file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CreateFile&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;built-in function CreateFile&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;win32file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CreateFile&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;AttributeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;Nonexistent module win32file (CreateFile)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;splitbrain&lt;/code&gt; is still &lt;em&gt;highly experimental&lt;/em&gt; and probably has issues with multiple threads.
I hope to stabilize it and incorporate it into the next release of RPyC (3.3). In the meanwhile,
you can experiment with it on RPyC's master branch and report bugs on github. It's likely it will
never be perfect, but heck, it's cool!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>ReHelloWorld</title>
   <link href="http://tomerfiliba.com/blog/ReHelloWorld"/>
   <updated>2012-08-06T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/ReHelloWorld</id>
   <content type="html">&lt;p&gt;Tada! The new design is here. The previous one was based on some Drupal theme I once used
(before moving to &lt;em&gt;github pages&lt;/em&gt;) that I tried to mimic when I barely new CSS. Over the past
eight months it just grew, patch by patch, until it became an inconsistent conglomerate. The new
site is inspired by the clean minimalism of sites like &lt;a href=&quot;http://daltoncaldwell.com/&quot;&gt;this&lt;/a&gt;
(of &lt;a href=&quot;https://svbtle.com/&quot;&gt;svbtle&lt;/a&gt; fame), attempting to reduce visual clutter and offer a more
coherent theme that reacts nicely to screens of all sizes (try to resize the browser to see).
If you have any feedback or insights, please share them in the comments below -- it's a work
in progress and I'd love to improve.&lt;/p&gt;

&lt;p&gt;I'm still working on the last installment of the &lt;em&gt;Javaism, Exceptions and Logging&lt;/em&gt; series,
but I'm buried in work on University projects (my &lt;a href=&quot;http://tomerfiliba.com/blog/ReedSolo&quot;&gt;watermarking&lt;/a&gt;
project turned out quite interesting, I'll elaborate on it when I get the chance) and my
day job, so it'll have to wait.&lt;/p&gt;

&lt;h2&gt;A Windows Story&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-08-06-windows.png&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Instead, I wanted to share a debugging experience I had today at work (together with the excellent
&lt;a href=&quot;https://twitter.com/RoyRothenberg&quot;&gt;@RoyRothenberg&lt;/a&gt;) of an enigmatic bug that appeared all of the
sudden when we added support for Windows 2012. Generally speaking, our product wraps one of the
darkest corners of operating systems: low level SCSI stuff that connects storage arrays and hosts.
It's never a pleasant sight, what goes on there, but the voodoo that goes on on Windows will
surely turn me religious one day.&lt;/p&gt;

&lt;p&gt;The problem was simple: we tried to send a SCSI inquiry to a certain device (which used to work),
but we got &lt;code&gt;Errno 6: Invalid Handle&lt;/code&gt;. It happened only the first time we tried to send the
inquiry -- all future attempts worked like charm, and it only happened on Windows 2012 64bit. The
problem was highly consistent: open a Python interpreter, the first inquiry fails, the following
ones work; open up a fresh interpreter and it reproduces.&lt;/p&gt;

&lt;p&gt;Our gut feeling was, &quot;okay, they fucked something up on Windows 2012 -- let's just put a retry
loop&quot;, but that didn't help at all. Any number of resend attempts failed with the same error, even
when we added a short sleep in between. Once we got back to the interactive interpreter and called
the function again - it worked, from that point on.&lt;/p&gt;

&lt;p&gt;Puzzled, we stuck a &lt;code&gt;code.interact()&lt;/code&gt; inside the resend loop; the first attempt failed,
the interactive prompt showed and we terminated it by &lt;code&gt;Ctrl+Z&lt;/code&gt; (not typing anything else).
Once we did that, the second retry attempt magically worked. But it got even more bizarre:
we moved the &lt;code&gt;code.interact()&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; any inquiry attempts... it popped up, we terminated it,
and then the &lt;strong&gt;first&lt;/strong&gt; inquiry attempt worked out of the box.&lt;/p&gt;

&lt;p&gt;We came to the conclusion that we had some sort of memory corruption going on, and that some of
field in our &lt;code&gt;ctype&lt;/code&gt; structs must be misaligned. We've seen this kind of behavior before when
memory corruption was involved. But the MSDN told us everything was of the right type and
alignment... In a desperate move, we zeroed the buffer that was passed to the kernel. This time,
the first attempt failed with &lt;code&gt;Invalid Handle&lt;/code&gt;, while the second failed with &lt;code&gt;Invalid
Parameter&lt;/code&gt; -- so the first attempt didn't even get to the point of looking at the input buffer!
Alas, it wasn't memory corruption after all! We felt hopeless.&lt;/p&gt;

&lt;p&gt;After some mindstorming, we got suspicious of &lt;code&gt;win32file&lt;/code&gt; and &lt;code&gt;ctypes&lt;/code&gt; and went on to inspect
very closely how they handled their parameters. A tedious investigation revealed that the code
invoked &lt;code&gt;DeviceIoControl&lt;/code&gt; (obtained via &lt;code&gt;ctypes.windll.kernel32&lt;/code&gt;) without setting the
function's &lt;code&gt;argtypes&lt;/code&gt;, so ctypes just had to guess. Everything was fine, except for the
first argument, the device handle, which was treated as a &lt;code&gt;DWORD&lt;/code&gt; for being an integer.&lt;/p&gt;

&lt;p&gt;The problem is, &lt;code&gt;HANDLE&lt;/code&gt; is not a numeric type but rather a disguised &lt;code&gt;void&lt;/code&gt; pointer, so
it's 8-bytes wide on 64bit platforms. When the kernel read in the arguments ctypes had placed on
the stack, it took the first and half of the second for the handle, which obviously turned to
be an invalid one.&lt;/p&gt;

&lt;p&gt;This, by itself, makes perfect sense, and should have happened every time. In fact, had it happened
every time, it would have been obvious... but what on earth could ever explain the strange
phenomena we've seen? How could it ever have worked the second time (with the very same arguments)?!
If the size of the first argument is wrong, all following ones are garbage. Does the kernel &lt;em&gt;learn&lt;/em&gt;
that our process mistakenly passed a 32bit handle? Does ctypes &lt;em&gt;come to the conclusion&lt;/em&gt; that the
first integer argument should actually be treated as a &lt;code&gt;HANDLE&lt;/code&gt; instead of a &lt;code&gt;DWORD&lt;/code&gt; --
after seeing &lt;code&gt;Errno 6&lt;/code&gt;? Is that the most sophisticated form of machine-learning ever seen, or what?
And it all happens inside the kernel or an FFI library? And how the hell does invoking
&lt;code&gt;code.interact()&lt;/code&gt; &lt;em&gt;before anything took place&lt;/em&gt;, could have averted the problem?! And how come it
never happened on previous versions of 64bit Windows (with the same version of Python and ctypes)?&lt;/p&gt;

&lt;p&gt;Windows, you bewilder me.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Javaism, Exceptions, and Logging: Part 2</title>
   <link href="http://tomerfiliba.com/blog/On-Exceptions"/>
   <updated>2012-07-09T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/On-Exceptions</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-07-09-i-fixed2.jpg&quot; class=&quot;blog-post-image&quot; title=&quot;Nesting Exceptions...&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Considering the reactions to the &lt;a href=&quot;http://tomerfiliba.com/blog/Javaism&quot;&gt;previous post&lt;/a&gt; in this
series, my intent was obviously misunderstood. Please allow me to clarify that &lt;strong&gt;I was not
attacking Java or Python&lt;/strong&gt;: Java is popular and has proven to be productive,
both as a language and as an ecosystem; the stylistic and semantic choices it makes are none of my
concerns (although I'm not a big fan). And as for Python, I was saying that it &lt;strong&gt;copied Java's
implementation&lt;/strong&gt; in some modules (and I think I've shown the correlation pretty well).
I said that it's silly, because &lt;strong&gt;Python is not subject to the same limitations&lt;/strong&gt; of Java,
which dictate how the Java implementation works. I'm not going to open the discussion over
whether OOP is good or bad, or mix-ins vs. interfaces, etc. -- I'm simply saying that &quot;Java
concepts&quot; (which I called &lt;em&gt;Javaisms&lt;/em&gt;) seem to enter Python &lt;strong&gt;for no good reason&lt;/strong&gt;, meaning,
in Python we have better ways to do it. I hope the scope of my discussion is clear now.&lt;/p&gt;

&lt;h2&gt;When Life Throws Lemons At You&lt;/h2&gt;

&lt;p&gt;In this installment, I'm going to discuss how to &lt;strong&gt;properly work with exceptions&lt;/strong&gt;, based on my
experience with large-scale Python projects. In fact, this series was born after I got frustrated
with the code quality of a certain library that my team develops. Instead of discussing specific
code snippets here, I want to share a some representative examples that I (as a user of that
library) encountered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I used a function in the spirit of &lt;code&gt;open_device(devfile)&lt;/code&gt;, and passed a nonexistent device file
(for testing purposes or by mistake). The underlying error was obviously &lt;code&gt;IOError(ENOENT)&lt;/code&gt;,
but what I got back was a silly &lt;code&gt;DeviceDoesNotExistError&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I called &lt;code&gt;get_device_info()&lt;/code&gt; and it simply returned &lt;code&gt;None&lt;/code&gt;. Further investigation showed that
my machine had a more recent version of a dependency installed on it, in which some method's name
had changed. At some point (deep down the stack), the code used &lt;code&gt;except Exception&lt;/code&gt; (catching
the unrelated &lt;code&gt;AttributeError&lt;/code&gt;) and translated it into a &lt;code&gt;DeviceError&lt;/code&gt;, under the assumption
that everything that gets thrown out of that module has to be a &lt;code&gt;DeviceError&lt;/code&gt;. Later,
&lt;code&gt;get_device_info&lt;/code&gt; (of a different module) swallowed this &lt;code&gt;DeviceError&lt;/code&gt; and returned &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I called a function such as &lt;code&gt;enumerate_all_devices()&lt;/code&gt; and it returned an empty list.
At first I was told &quot;Of course, this library isn't supposed to work on Ubuntu, only on RHEL&quot;.
Further (and tedious) investigation showed it simply needs to run as &lt;code&gt;root&lt;/code&gt;; the code just
assumed that any error during the execution an external tool meant it's not installed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This kind of stuff happens to me every time I get to an unexplored corner of the code, and I've
already devised a method for debugging such cases: I comment-out all exception handling code along
the way, until I find the actual error. In fact, this is essentially the treatment that I'm about
to suggest here. The first rule of exception handling is: &lt;strong&gt;Don't handle exceptions&lt;/strong&gt;, just let
them pass through.&lt;/p&gt;

&lt;h2&gt;Don't Catch Broadly&lt;/h2&gt;

&lt;p&gt;&lt;highlight&gt;Always catch only the most-derived/most-specific exception.&lt;/highlight&gt;
I believe this rule is very obvious
in theory, but harder to follow in practice: the number of exceptions might be large and their
handling similar; you have to &lt;em&gt;import&lt;/em&gt; specific exceptions from libraries, which tightly-couples
your code with implementation details; some libraries don't use a common exception base class for
all of their exceptions, which leads to many isolated &lt;code&gt;except&lt;/code&gt;-clauses.&lt;/p&gt;

&lt;p&gt;All in all, you might have attenuating circumstances, but try to stick to this rule as much
as possible. On the other hand, &lt;strong&gt;never use a bare &lt;code&gt;except:&lt;/code&gt;&lt;/strong&gt;! Such an &lt;code&gt;except&lt;/code&gt;-clause will
catch &lt;strong&gt;all exceptions&lt;/strong&gt;, including &lt;code&gt;SystemExit&lt;/code&gt; and &lt;code&gt;KeyboardInterrupt&lt;/code&gt;, so unless you plan
to loose the ability to Ctrl-C a running program, or even prevent it from terminating gracefully,
take the extra step and use &lt;code&gt;except Exception&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Don't be Overprotective&lt;/h2&gt;

&lt;p&gt;A tendency I find in many programmers is being &lt;em&gt;overprotective towards their users&lt;/em&gt;, to the point
where it seems like paternalism. It's as if they try to &quot;hide away&quot; all the complexities of life
and present the user with an easy-to-swallow explanation. I should say that this phenomena
virtually doesn't exist in &lt;strong&gt;open-source&lt;/strong&gt; code, so you might have never seen it, but in
closed-source projects I find it all over the place. In fact, fellow programmers have told me
that's exactly what they're doing -- protecting their users.&lt;/p&gt;

&lt;p&gt;Well, as the saying goes, &lt;strong&gt;we're all consenting adults here&lt;/strong&gt;. You should expect your users, as
&lt;strong&gt;programmers&lt;/strong&gt;, to have sufficient background; don't treat them like babies, and don't try to
protect them by throwing a &quot;user-friendlier&quot; &lt;code&gt;FileNotFoundError&lt;/code&gt; in place of the &quot;raw&quot;
&lt;code&gt;IOError&lt;/code&gt;. Besides, keep in mind that the underlying exception usually holds all the needed
information in a very readable manner, e.g.,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Traceback (most recent call last):
  File &quot;&amp;lt;stdin&amp;gt;&quot;, line 1, in &amp;lt;module&amp;gt;
IOError: [Errno 2] No such file or directory: '/dev/nonexistent'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and anyone with some common sense would be able to cope with it.
&lt;highlight&gt;Unless you can add meaningful information to the error, just let
whatever came at you propagate up cleanly&lt;/highlight&gt; -- we'll take it like men (or women!).&lt;/p&gt;

&lt;h3&gt;A Note On Real Users&lt;/h3&gt;

&lt;p&gt;A question then arises: &lt;strong&gt;what about non-programmer end-users?&lt;/strong&gt; What if my product's a GUI/CLI
and a nasty stack trace suddenly shows up?&lt;/p&gt;

&lt;p&gt;Well, first of all, &lt;strong&gt;this rule only deals with libraries&lt;/strong&gt; and other products whose end users are
programmers. But on second thought, would it matter whether an &lt;code&gt;IOError&lt;/code&gt; or a &lt;code&gt;FileNotFoundError&lt;/code&gt;
reaches the surface? The human user cares mostly for a descriptive and easy to understand &lt;strong&gt;error
message&lt;/strong&gt;; the traceback or exception's type are mostly of interest to programmers.
But then again, when it comes to non-programmers, I don't want to get into generalizations.
They might as well &lt;strong&gt;not be&lt;/strong&gt; consenting adults...&lt;/p&gt;

&lt;h2&gt;Don't Wrap Exceptions&lt;/h2&gt;

&lt;p&gt;Prior to Python 3, raising an exception during the handling of one, meant the original traceback
was lost. This has been finally solved, but Python 2.x still accounts for the majority of the
code-base. Once you loose the traceback, debugging the problem is much harder as you can't use a
debugger (&lt;code&gt;pdb&lt;/code&gt;) or even tell &lt;em&gt;where&lt;/em&gt; the exception came from... And when it happens off-site,
on a customer's production server, you're screwed.&lt;/p&gt;

&lt;p&gt;I believe exception wrapping in Python is a &lt;strong&gt;legacy of Java&lt;/strong&gt; that crept into Python (a &lt;em&gt;Javaism&lt;/em&gt;).
It resonates as the Java mind-set, where you'd like a library to be &lt;em&gt;contractually obliged&lt;/em&gt; to
throwing only certain exceptions. For instance, a queue library might raise exceptions such as
&lt;code&gt;QueueFull&lt;/code&gt; and &lt;code&gt;QueueEmpty&lt;/code&gt;, both of which derive from &lt;code&gt;QueueError&lt;/code&gt;. Later, we add support
for dumping a queue to a file, where an &lt;code&gt;IOError&lt;/code&gt; might happen; because we're already &quot;obligated&quot;
to throwing only &lt;code&gt;QueueErrors&lt;/code&gt;, they might wrap the underlying &lt;code&gt;IOError&lt;/code&gt; by a &lt;code&gt;QueueError&lt;/code&gt;.
&lt;strong&gt;Don't do that&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is reasonable that &lt;code&gt;FooLibrary&lt;/code&gt; would only throw exceptions that derive from &lt;code&gt;FooError&lt;/code&gt;,
but only when these exceptions &lt;strong&gt;originate&lt;/strong&gt; in &lt;code&gt;FooLibrary&lt;/code&gt;. An underlying &lt;code&gt;IOError&lt;/code&gt; has
nothing to do with your library, it could happen any time and for various reasons. The same goes for
an HTTP library that might get an &lt;code&gt;ECONNRESET&lt;/code&gt; while talking over a socket -- the underlying
&lt;code&gt;socket.error&lt;/code&gt; is clearly not an &lt;code&gt;HTTPError&lt;/code&gt; (or any of its descendants), and should not
be wrapped by one. Besides, there are so many things that could go wrong, especially in a dynamic
language like Python, that it's impossible to wrap everything.&lt;/p&gt;

&lt;p&gt;It only makes sense to wrap an underlying exception where you can provide additional information
on the cause of it, or where you want to &lt;em&gt;change the semantics&lt;/em&gt; of it. A classical such case is
&lt;code&gt;connect_with_retries()&lt;/code&gt;, where you might want to allow several attempts before giving up. Here,
you'd probably want to &quot;accumulate&quot; the intermediate exceptions and raise a
&lt;code&gt;ConnectionError(&quot;%d connection attempts failed&quot;, accum_exceptions)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bottom line: &lt;highlight&gt;wrap only where you &lt;strong&gt;add information&lt;/strong&gt; to the
underlying exception;&lt;/highlight&gt; there has to be a &lt;strong&gt;good reason&lt;/strong&gt; for wrapping.&lt;/p&gt;

&lt;h2&gt;Don't Handle Exceptions&lt;/h2&gt;

&lt;p&gt;Let me rephrase that: exceptions should be handled only&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;where it's possible to &lt;strong&gt;fix/recover&lt;/strong&gt; from the problem. For instance, if you get an &lt;code&gt;EINTR&lt;/code&gt;
error when &lt;code&gt;accept()&lt;/code&gt;ing on a socket, it makes sense to swallow it and retry. Another use case
is for fallbacks: first try to take the short way, and if it fails, take the long one.
There are &lt;strong&gt;many more&lt;/strong&gt; examples of handling an exception, of course, but you have to ask
yourself &lt;em&gt;whether you're really handling the problem or just masking it&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;where &lt;strong&gt;cleanup/rollback&lt;/strong&gt; is necessary. It may be the case that you need to run rollback code
only if an exception occurs (to release resources, etc.), so a &lt;code&gt;finally&lt;/code&gt;-clause or a &lt;em&gt;context
manager&lt;/em&gt; won't do. In this case you can &lt;code&gt;except Exception&lt;/code&gt;, do the rollback, and &lt;code&gt;raise&lt;/code&gt;
(without passing any arguments to &lt;code&gt;raise&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I stand corrected by Nick Coghlan -- you can use context managers for the very same
effect. Forgot about that.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;in the &lt;strong&gt;main function&lt;/strong&gt;. Instead of letting the application crash with a traceback, you might
want to log the exception to a file, pop up a message box, ask the user what to do next, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In other words: &lt;highlight&gt;handle exceptions only where you're actually
&lt;strong&gt;handling&lt;/strong&gt; them.&lt;/highlight&gt; If you're not sure, leave it that way -- you can always add
&lt;code&gt;except&lt;/code&gt;-clauses later.&lt;/p&gt;

&lt;p&gt;It might seem trivial, but you'd be surprised how many times I find
code that handles exceptions for no good reason. For example, people think that by swallowing
all sorts of exceptions and returning &lt;code&gt;None&lt;/code&gt;, they make their code &quot;more robust&quot;; &lt;strong&gt;that's lying
to yourself&lt;/strong&gt;. You take a problem and make it worse, as it's very likely you'd lose the original
details and &lt;em&gt;hide real issues&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I've encountered countless cases of code that follows a pattern such as &lt;code&gt;except Exception:
log.error(...)&lt;/code&gt;, which &lt;strong&gt;hides bugs&lt;/strong&gt; like a misspelled variable (&lt;code&gt;NameError&lt;/code&gt;). Logging is not
handling the exception &lt;em&gt;(more on this in part 3)&lt;/em&gt;. In the end, nobody ever reads the log, or even
takes the time to properly configure it, so you ship a &quot;very robust&quot; product that has half the
functionality you think it has.&lt;/p&gt;

&lt;h2&gt;Closing Words&lt;/h2&gt;

&lt;p&gt;The lesson to be learnt here is: &lt;em&gt;think before you act&lt;/em&gt;. Don't act dogmatically, don't follow Java
paradigms for no reason, and try to keep your footprint as low as possible when it comes to
error handling. As the saying goes, &lt;strong&gt;shit happens&lt;/strong&gt;; calling it in other names does not make it
any better. Files disappear, permissions get screwed, devices disconnect, sockets die,
everybody lies. That's life.&lt;/p&gt;

&lt;p&gt;Going back to the three bullets I opened this post with, you can see how by being &lt;em&gt;overprotective&lt;/em&gt;
and by excessively wrapping exceptions, an &lt;code&gt;AttributeError&lt;/code&gt; became a &lt;code&gt;DeviceError&lt;/code&gt;, which
then became &lt;code&gt;None&lt;/code&gt;. And you can see now why the first thing I do is remove all
exception-handling code along the way: most of the times it just masks the real error, making it
harder to diagnose, while adding little or no added value at all. You don't make your code more
robust by sweeping problems under the carpet: &lt;highlight&gt;good code crashes,
allowing tests to uncover more bugs, increasing robustness.&lt;/highlight&gt;&lt;/p&gt;

&lt;h2&gt;On the Granularity of Exception Classes&lt;/h2&gt;

&lt;p&gt;Some people are rather laconic and use a single exception for everything. I've seen people who were
so lazy that they used &lt;code&gt;raise Exception(&quot;foo&quot;)&lt;/code&gt; directly, instead of deriving an exception class
of their own... People, it only takes &lt;strong&gt;one line&lt;/strong&gt; to derive an exception class, there's no excuse
for being &lt;strong&gt;that lazy&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;On the other hand, some people are way too verbose, defining specific exceptions for every minor
detail. They end up with dozens of exception classes for each module, many of which are logically
overlapping. This makes the implementation cumbersome, and, in fact, might not be useful at all
for your users: they usually won't care for such granularity, and you risk contaminating your
interface with implementation details.&lt;/p&gt;

&lt;p&gt;The rule to follow here is: &lt;highlight&gt;the granularity at which exceptions
are defined should match the granularity at which exception handling is done&lt;/highlight&gt;; define
separate exceptions (only) where it makes sense to handle one differently than the other.&lt;/p&gt;

&lt;p&gt;For example, it makes sense to handle a &lt;code&gt;ConnectionError&lt;/code&gt; differently from an
&lt;code&gt;InvalidCredentials&lt;/code&gt; error, but there's usually little sense in making the distinction between
&quot;connection failed because server is not listening&quot; to &quot;connection failed because server crashed
after accepting us&quot;. But in any case, be sure to &lt;strong&gt;include all the available information&lt;/strong&gt;
in the error message, as it's important for logging/diagnostic purposes.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>כולם מדברים על גיוס, אף אחד לא מדבר בשכל</title>
   <link href="http://tomerfiliba.com/etc/Gius-Lekulam"/>
   <updated>2012-07-04T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/etc/Gius-Lekulam</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-07-04-bitch.png&quot; class=&quot;blog-post-image&quot; style=&quot;width: 180px;&quot; title=&quot;10gag.co.il&quot;/&gt;&lt;/p&gt;

&lt;h2&gt;כלבתא במטותא&lt;/h2&gt;

&lt;p&gt;אז כולם התחילו לדבר עכשיו על &lt;strong&gt;גיוס חרדים&lt;/strong&gt;. אפילו &lt;a href=&quot;http://www.ynet.co.il/articles/0,7340,L-4250737,00.html&quot;&gt;איציק שמולי המתחנחן&lt;/a&gt;
נרתם פתאום למשימה... שוב עולה בנחיריים ריח של בחירות, הפעם תחת האמתלה המטופשת הזו, ואני שואל - לְמה?
ראשית, איזה סיבה יש לקיים בחירות בארץ? מה יוצא לנו מזה? הרי זו רק רוטציה בין אותם אנשים, כבר 15 שנים. אותם
פרצופים כל כנסת (יש שמחליפים מפגלה או שתיים בדרך) שיעשו הכל בשביל להיאחז בכיסא וביכולת להשתכר בלי
לעשות הרבה חוץ מלדבר. לא רציתם אותו בתור X, תקבלו אותו בתור Y - הזיכרון שלנו קצר וגם ככה הכל מנוהל על
ידי לוביסטים, אז מה זה כבר משנה.&lt;/p&gt;

&lt;p&gt;שנית, במה שונה המצב היום מלפני חמש שנים, בכל הנוגע לתעסוקה של-, תקציבים ממשלתיים הניתנים ל-
או לגיוסם של החרדים? רוב הציבור ותנועות כאלו ואחרות זועקות לגבי זה כבר שנים... איך קרה שבחודשיים-שלושה
האחרונים (רמז: מאז התרגיל המסריח של מופז-ביבי-ברק) זה עבר לחזית הבמה? ומה שונה הפעם שצריך להפיל את
הממשלה על רקע זה? ליברמן יפרוש בגלל גיוס חרדים -- אבל לא בגלל נישואים אזרחיים? הכבוד של ח&quot;כ מולה נרמס
לפתע בגלל פירוק ועדת פלסנר -- ולא, נניח, מהיחס שהקהילה שלו מקבלת, או מזה שהכו יוצא אתיופיה כי חשבו
שהוא מסודן (השם ישמור)? זה מריח הרבה יותר כמו עוד ספין שנועד להסיט את תשומת הלב הציבורית מדברים שבאמת
לא נוחים לממשלה, כמו המחאה החברתית וכו'. להבטיח לגייס חרדים זה קל, להבטיח עתיד לדור שלם זה קשה
(גם באירופה).&lt;/p&gt;

&lt;p&gt;אפשר להמשיך לדוש בכל מיני ספקולציות ולתהות מה יוליד יום בהקשר של גיוס חרדים, אבל אני רוצה לפתוח חזית אחרת,
ברשותכם: אני רוצה &lt;strong&gt;לשחוט את הפרה הקדושה שנקראת &quot;צבא העם&quot;&lt;/strong&gt;. נמאס לי כבר מהדמגוגיה המתחסדת הזו.
נתחיל בגילוי נאות: מי שמכיר אותי אישית יודע שהייתה לי מערכת יחסים מאוד טעונה עם הצבא, אבל אני שם אותה
מאחורי ומתכוון לפרוט את הנקודות בצורה אובייקטיבית עד כמה שאפשר. ולכל המצקצקים האוטומטיים, שירתתי
שירות מלא. זה כמובן לא רלוונטי, אבל אחרת תפסלו את הניתוח שלי מראש תחת הכותרת &quot;משתמט סמולן&quot;. זה כנראה
יקרה גם ככה, אבל לפחות כיסיתי את עצמי פה.&lt;/p&gt;

&lt;h2&gt;מיליטריזם חברתי&lt;/h2&gt;

&lt;p&gt;נתחיל בדברים הברורים: &lt;strong&gt;אנחנו צריכים צבא&lt;/strong&gt;. השכנים שלנו לא מחכים לנו עם פרחים בקנה, וזה ברור לכל בר דעת.
נמשיך עם עוד דברים ברורים: השנה היא לא 1950, הסולידריות החברתית כמעט נעלמה ואת מקומה תפס האינדיווידואליזם.
נתוני הגיוס היורדים משנה לשנה מראים שהאתוס המיליטריסטי שאנחנו גדלים עליו הולך ונשחק, וזה מתבטא בכך שרוב
הנערים הנורמלים (כלומר, אלו שלא מתחנכים על ברכי האל בהתנחלויות) מעדיפים לעשות עם עצמם משהו מועיל במקום
לשחק בחייל-וקצין. באופן כללי כסף קונה הכל, והתרבות שלנו נהייתה שטוחה כמו התרבות האמריקאית הנערצת
(רק שאמריקה מספיק גדולה כדי לקיים תת-תרבויות נוספות, ואנחנו לא). ברוכים הבאים לישראל מודל 2012 --
הצטרפנו סוף סוף למשפחת העמים. או&quot;ם-שמום זה אנחנו.&lt;/p&gt;

&lt;p&gt;אם בשנות החמישים הצבא שימש כור היתוך ליהודים תועים מכל העולם ויצר אצלם זהות לאומית וכו', הרי שזה לא המצב
היום. האוכלוסיה גדלה, המצוקות הקיומיות של המדינה הרבה פחות קשות היום (למרות מה שמספרים לנו), יש לנו עם
שדובר (בצורה עילגת) שפה לאומית... אפשר לסכם את 60 השנה הראשונות בכך שהקמנו כאן מדינה בת-קיום, וכעת
הגיע הזמן להכיר בעובדה &lt;strong&gt;שצבא העם סיים את תפקידו&lt;/strong&gt;. זה נכון כבר זמן מה, אבל אנחנו מסרבים להכיר בעובדות.
אין ספק שעם הזמן זה יחלחל, כאשר הדור שגדל היום יגיע למוסדות השלטון. עוד 20 שנה זה יהיה ברור כשמש:
אנחנו רוצים פלייסטיישן ולא פ&quot;זצטות, וזה מאוד הגיוני.&lt;/p&gt;

&lt;h2&gt;אתוס שמתוס&lt;/h2&gt;

&lt;p&gt;לא הצלחתי להשיג נתונים מהימנים לגבי ההתפלגות, אבל ככל הנראה המערך הלוחם של צה&quot;ל מונה בין 15 ל 20 אחוז
מכלל החיילים, תומכי לחימה מהווים בערך עוד 20-30 אחוז, והשאר (מעל 50%), כמו שאומרים, ג'ובניקים.
אפשר להתווכח גם איך סופרים, האם נהג ג'יפ הוא לוחם והאם אפסנאי הוא תומך לחימה -- אבל אני לא רואה צורך
להכנס לזה. יש לנו &lt;strong&gt;חוק גיוס חובה&lt;/strong&gt;, מה שאומר שכל נער/ה בן/ת 18 (לצורך העניין) חייב/ת להתגייס,
אבל בצד השני של המטבע מתסתתרת עובדה די מצחיקה: &lt;strong&gt;הצבא חייב לגייס את כולם&lt;/strong&gt;. זה אולי נשמע טריוויאלי,
אבל אנשים נוטים לשכוח &lt;strong&gt;שהצבא ממש לא צריך את כולם&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;לשם הדיון, נקח חייל היפותטי בשם דני. דני לא חדור מוטיבציה, הוא לא רוצה להיות קרבי ולא מתכוון להישכב על רימון
בשביל אף אחד, אבל הוא משרת  כי &quot;זה מה שכולם עושים&quot;. נחמד לו לשבת בשלישות ברמת גן, במזגן, ולהעביר
את היום בלהעביר דפים מהמדפסת למגרסה. גם למפקדים שלו זה נחמד. אולי הוא ממר&quot;מניק והוא בכלל כותב
שאילתות SQL שרצות על mainframe מימי מלחמת השחרור. בכל אופן, יש לו חברים טובים שם, הוא עושה יומיים
שמירות בחודש וגם קצת מטבחים, חוזר הביתה כל יום ונהנה מהחיים. או להיפך - הוא עשוי להיות תקוע תחת מפקד
שמתעלל בו רגשית, בין אם מי מהם מבין את זה או לא, וללא כל מסגרת תומכת (המש&quot;קית ת&quot;ש התגייסה לפני
שבועיים ובעיקר רוצה ללכת הביתה בחמש). הוא עשוי גם להגיע לנקודת שבירה ולהתאבד עקב &quot;חוסר התאמה
למסגרת&quot;, ומכיוון שכל התאבדות כזו כורתת עוד ענף באתוס הלאומי, הצבא כל כך מתעקש להסתיר את הפרטים.
זה עוול איום, אבל נשכח ממנו לצורך הדיון, ונניח שדני נשאר בחיים &lt;a href=&quot;http://www.aka.idf.il/miluim/templates/inner.asp?catId=58705&quot;&gt;ומשתחרר בגבורות&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;עכשיו בואו נעשה ניתוח amortized של עלות חייל דוגמת דני, שהצבא היה יכול להסתדר גם בלעדיו. דני צריך מפקד?
רס&quot;ר שיצעק עליו? כיסא לשבת עליו? עמדת מחשב, חשמל, מדים (ומשטרה צבאית שתפקח על הלבוש שלו), נסיעות
בתחבורה ציבורית, אוכל (ולכן גם טבחים), ציוד (ולכן גם אפסנאים ונהגי משאיות), מגוון שירותי שלישות/חינוך,
בריכה ומציל (בחיל האויר) וכו' וכו'. אה, וכמובן שיש לו משכורת, שבמקרה של דני היא זניחה, אבל שרשרת הפיקוד
שמעליו מגיעה לסכומים יפים. ככה מקבלים בסיסים שלמים שכל הצידוק לקיומם הוא הם עצמם (והעובדה שצריך למצוא
לכל החיילים מה לעשות), כך שהערך המוסף שלהם, איך נאמר, מוטל בספק. רק בשביל לסבר את האוזן,
אני לא תוקף את השלישות ספציפית, אין לי שום דבר נגדם, אני תוקף את השיטה.&lt;/p&gt;

&lt;p&gt;אז כמובן שדני עצמו לא מקבל טבח פרטי או שרשרת פיקוד אישית: הוא מקבל נתח קטן מכל שירות - אחד חלקי מספר
הדניים שבצבא (וזה נסכם כלפי מעלה, כשגודל כל שכבה קטן באופן לוגריתמי). אבל אם נסתכל בסכום על פני כל
הדניים בכל בסיס שהתועל בקיומו זניחה -- מדובר על עשרות מיליארדי שקלים, מתוך תקציב משרד הביטחון שעומד על
50 מיליארד.&lt;/p&gt;

&lt;h2&gt;על העיוורון&lt;/h2&gt;

&lt;p&gt;רצה הגורל והרבי אמר &quot;מהיום כולם מתגייסים, זו מצווה&quot;. עשרות אלפי אברכים בגילאי גיוס צובאים על שערי הבקו&quot;ם,
הצבא מתמוגג, מעלה את כולם על אוטובוסים, בסיסי הטירונות באקסטזה... ואז מה? קרביים כנראה שהם לא יהיו,
בכל אופן רובם לא. וצריך למצוא להם בסיסים/מדורים כשרים למהדרין, בלי בנות (תועבה!), ועם שיעורי תורה בוקר וערב.
אז חלק יהיו מתכנתים, חלק שלישים, חלק משגיחי כשרות, נהגים... אוקי ומה הלאה? נבנה את בסיס &quot;לשם שמיים&quot;
בשטחים הפתוחים האחרונים שנותרו ליד בני-ברק, או אולי על גבעה בשומרון, ואז מה? אתם מסוגלים בכלל לשערך
את העלות של דבר כזה? ואת חוסר התועלת בו, גם יחד? אז נכון, אולי חלק ירכשו ככה מקצוע, זה גם משהו.
אבל למה שבעולם של היום, בשנת 2012, &lt;strong&gt;הצבא הוא זה שיעצב את התרבות שלנו?&lt;/strong&gt; &quot;צבא בונה עם בונה צבא&quot;?
למה שזה לא יקרה במסגרת אזרחית? המיליטריזם הזה עבר זמנו.&lt;/p&gt;

&lt;p&gt;עכשיו האתוס שמונחל בכם, כמו גם הצורך הישראלי הבסיסי לא לצאת פרייארים, זועק בקול גדול
&lt;em&gt;געוולד! חייבים לגייס את כולם! שוויון בנטל!&lt;/em&gt;, אבל זו אינדוקטרינציה של אמרות חלולות ששמעתם מאז ילדותכם.
מה &lt;strong&gt;תעשו&lt;/strong&gt; עם כולם? מי &lt;strong&gt;ישלם&lt;/strong&gt; על זה? &lt;strong&gt;מעמד הביניים, כרגיל, ייצא הפראייר הגדול&lt;/strong&gt;. הרי כמו
שאתם נכנעים לחתונה ברבנות, משלימים עם חוסר תחבורה ציבורית בשבת (ורחובות שנחסמים) ומוכנים לספוג את העלות
של הכשרות על המזון בארץ -- כך אתם גם תשמחו להקל עם החרדים שמשרתים: לא לשבץ אותם לתורניות בשבת,
לאפשר להם ללמוד גמרא שלוש שעות ביום, ועוד היד נטויה. ובסופו של דבר, אברך שיסיים שירות יהיה זכאי לשלוש
שנות לימודים בכולל חינם... &lt;a href=&quot;http://www.idf.il/1133-15370-he/Dover.aspx&quot;&gt;מה לא תעשו&lt;/a&gt;
בשביל לעודד אותם להתגייס.&lt;/p&gt;

&lt;p&gt;אתם תמשיכו לשלם מיסים, לעשות מילואים ולהקשיב לשירים של הדג-נחש.&lt;/p&gt;

&lt;h2&gt;מודל חלופי&lt;/h2&gt;

&lt;p&gt;רב נגד שמנהל צי משאיות מקבל משכורת על פי הדרגה שלו והגמו&quot;שים שהוא צבר (שזה כמו מדבקות &quot;הייתי גיבור&quot;),
מה שאומר שהוא יכול לקבל מעל 20 אלף ש&quot;ח בחודש. מחוץ לצבא לא ניכר שנהגי משאיות  הם מעשירי הארץ, וברור
שהדיסוננס הזה עולה לנו המון כסף. אמנם מצפים מנהג צבאי שייכנס עם המשאית ללבנון בעת מלחמה, אבל הייתי
מהמהר שמי שנוהג במשאית הוא חפ&quot;ש ולא רנ&quot;ג -- כלומר יש &lt;strong&gt;יחס הפוך בין רמת התגמול לבין הצרכים המבצעיים
הנדרשים&lt;/strong&gt;. זה נכון בעוד הרבה מאוד תחומים בצבא, ועושה רושם שאם נסתכל מפרספקטיבה יותר רחבה -- רוב הצבא
מתנהל הפוך מההיגיון. ג'וזף הלר אמר את זה כבר בשנות ה 60 (וכל מי שלא קרא את מלכוד 22, שייתבש לו), אבל
זה לא הופך את זה לפחות נכון.&lt;/p&gt;

&lt;p&gt;נתחיל מאפס: לוחמים וקצינים צריך. כך גם טנקים ומטוסים ורובים. אם נהפוך את &quot;צבא העם&quot; &lt;strong&gt;לצבא מקצועי&lt;/strong&gt;,
שמתעסק רק במה שקשור בלחימה ובטחון שוטף, נקבל תמונה הרבה יותר הגיונית. את שאר השירותים, כמו תובלה ואוכל,
הצבא יכול לקבל מגורמים חיצוניים (באותה מידה שקבלנים בונים את הגדר בגבול עם מצריים, ולא חיל ההנדסה).
כמובן שיש עוד תפקידי מעטפת, כמו פרמדיקים, רופאים, טכנאי מטוסים ואפסנאים -- אבל אם הצבא יהיה מוכוון
מטרה (כלומר, לחימה), ההיקף של תפיקידי המעטפת יהיה הרבה יותר קטן. למשל, המשטרה צבאית תוכל להיעלם
והאחריות על חקירות תוטל על גוף חוץ-צבאי, כמו המשטרה הרגילה. כנ&quot;ל לגבי מערכת המשפט הצבאית.&lt;/p&gt;

&lt;p&gt;מכיוון שכוח האדם יהיה הרבה יותר מצומצם, יתפנה אחוז ניכר מהתקציב: הלוחמים יוכלו לקבל משכורת הגיונית וציוד
מודרני (נניח, אפודי מגן וכלי רכב מהמאה הנוכחית). באופן כללי, ברגע שלוחמים יתוגלמו כספית, הרבה אנשים יפנו
למסלול הזה ואפשר יהיה להעביר את משימות האבטחה השוטפת לשכירים -- כמו מאבטחים (תחשבו על מאבטחים
בנתב&quot;ג, לא בקניון). פתאום יהיו אנשים עם מוטיבציה אמיתית לשרת, ולא כאלה שמכריחים אותם. כמובן שבהייטק
המשכורות יהיו גבוהות יותר -- אבל היות &lt;a href=&quot;http://he.wikipedia.org/wiki/%D7%94%D7%A9%D7%9B%D7%A8_%D7%94%D7%97%D7%A6%D7%99%D7%95%D7%A0%D7%99&quot;&gt;והשכר החציוני&lt;/a&gt;
בארץ עומד על כ 6000 ש&quot;ח בחודש, נראה שיש מספיק אנשים שישמחו לחתום. כמו כן, אל תשכחו
שהמדינה גוזרת קופונים יפים על המיסים של עובדי ההייטק ושכל מכירה של סטארט-אפ משמחת את קופת האוצר.
תחשבו גם על זה בתור שירות.&lt;/p&gt;

&lt;p&gt;במודל הזה אפשר יהיה לדרוש שכל אזרח במדינה, בהגיעו לגיל 18 וללא יוצא מן הכלל, יעבור טירונות של חודש-חודשיים,
בה הוא ילמד להחזיק נשק וקצת איך עובדת המערכת. אח&quot;כ הוא יוכל לבחור בין שירות אזרחי (התנדבות בבית חולים,
שיטור קהילתי, סיוע לקשישים, עזרה לתלמידים וכו') לבין שירות צבאי. השירות הצבאי יהיה &lt;strong&gt;מתגמל כספית&lt;/strong&gt;,
יאפשר הגשמה עצמית (&quot;תמיד רצית לנהוג בטנק ולא היה לך רישיון?&quot;) ויספק הכשרה מקצועית שתוכל לשמש אותו
לאחר מכן. שירות אזרחי ייזכה אותו במלגת קיום. כל אחד יוכל למצוא את מקומו במערכת &lt;strong&gt;ולתרום לחברה&lt;/strong&gt;:
חרדים למשל יוכלו לשרת במגוון מקומות שמתאימים לאורח החיים שלהם, ועדין למצוא כמה שעות ביום ללימוד תודה.
כל שנתיים האזרחים עד גיל 40 יקראו לשבועיים של שירות מילואים מרוכז, בשביל לרענן את הכישורים של מי בחר לא
להיות חייל, כך שבעיתות מצוקה יהיה מערך מילואים מתפקד (כמובן שלא ברמת המיומנות של הלוחמים, אבל כזה
שיוכל להחליף את משימות הבטחון השוטף).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;אפשר לפתח את המודל הזה עוד הרבה&lt;/strong&gt; -- זו כמובן רק סקיצה. ברור לי שיש כאן מקרי קצה שלא חשבתי עליהם,
והיות והמספרים המדויקים חסויים, אני לא יכול לאמוד את החיסכון בעלויות. תקראו לזה תחושת בטן, אבל אם נוותר
על 60% מהצבא של היום יש לי הרגשה שנישאר עם עודף והרי אף אחד לא חושב &lt;a href=&quot;http://www.haaretz.co.il/magazine/1.1743303&quot;&gt;שהיום המצב מזהיר&lt;/a&gt;.
לפחות נקבל חברה יותר מתוקנת.&lt;/p&gt;

&lt;h2&gt;ועוד פרט אחד קטן לסיום&lt;/h2&gt;

&lt;p&gt;למה לעזאזל אמ&quot;ן כפוף לצבא? הוא צריך להיות גוף חיצוני שכפוף ישירות למשרד הבטחון, כמו גופים נוספים
בקהיליה -- וכמו שמקובל ברוב העולם. כמובן שהמודל המוצע מניח שאמ&quot;ן נמצא מחוץ לצבא.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Javaism, Exceptions, and Logging: Part 1</title>
   <link href="http://tomerfiliba.com/blog/Javaism"/>
   <updated>2012-07-03T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Javaism</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-07-03-no-java.png&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I'm working nowadays on refactoring a large Python codebase at my workplace, and I wanted to share
some of my insights over two some aspects of large-scale projects: exceptions, logging, and
a bit on coding style. Due to it's length, I decided to split it over three installments; the first
covers &lt;em&gt;Javaism&lt;/em&gt; and an introduction to the issues of working with exceptions. &lt;strong&gt;Part 2&lt;/strong&gt; suggests
&quot;best practices&quot; concerning exceptions in Python, and &lt;strong&gt;part 3&lt;/strong&gt; will cover logging (when, how,
and how much).&lt;/p&gt;

&lt;h2&gt;Javaism&lt;/h2&gt;

&lt;p&gt;From my long experience in the programming world, I get the feeling that many programmers
(even those fluent in Pythonspeak) come from a rich Java/.NET background, where they've acquired
their programming skills and mind-set. Now converted-Pythonists, they are still the &quot;speakers&quot;
of a second language, and they can't deny their mother tongue. In the context of this post, I'll
refer to this as &lt;em&gt;Javaism&lt;/em&gt;, or &lt;em&gt;thinking Java in Python&lt;/em&gt;. Of course it might as well be C# or C++,
but Java is the umbrella term.&lt;/p&gt;

&lt;p&gt;You don't have to go far to see examples of it, for Javaism didn't skip Python's standard library:
modules/packages such as &lt;code&gt;logging&lt;/code&gt;, &lt;code&gt;unittest&lt;/code&gt; and &lt;code&gt;threading&lt;/code&gt; where ported almost
isomorphically from Java. On the surface, you might encounter &lt;em&gt;camelCase&lt;/em&gt; names (&lt;code&gt;getLogger&lt;/code&gt;),
but the verbosity and over-complicated nature of Java and its inheritance methodology can be seen
anywhere. For instance, recall the complexity of setting up a logger (I have to look it up every
time), or the &lt;code&gt;threading.Thread&lt;/code&gt; class... I really don't wish to digress here, but I feel that a
concrete example would make this point clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The canonical way to write thread functions is by subclassing &lt;code&gt;Thread&lt;/code&gt; and implementing
&lt;code&gt;run()&lt;/code&gt;; you can pass a callback (called
&lt;a href=&quot;http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#Thread(java.lang.Runnable&quot;&gt;target&lt;/a&gt;),
but it seems like an afterthrought (for once, it's not the first argument of the constructor).&lt;/p&gt;

&lt;p&gt;Recall that &lt;em&gt;anonymous classes&lt;/em&gt; weren't always there in Java, so extending a class was the
shortest way to emulate first-class functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Speaking of the Thread constructor -- it takes so many optional arguments (&lt;code&gt;group&lt;/code&gt;?!),
but none for &lt;code&gt;daemon&lt;/code&gt;. For that, you have to imperatively call &lt;code&gt;setDaemon()&lt;/code&gt; afterwards.&lt;/p&gt;

&lt;p&gt;Why? Because Java doesn't have &lt;em&gt;keyword arguments&lt;/em&gt;, so by adding an additional argument you
double the number of overloaded constructors (exponential growth), while get/set properties
behave &quot;linearly&quot;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, you first &lt;em&gt;instantiate&lt;/em&gt; the thread object, then &lt;code&gt;start()&lt;/code&gt; it... where's the sense in that?
What can you &lt;em&gt;do&lt;/em&gt; with an &lt;em&gt;unstarted&lt;/em&gt; thread object (other than calling &lt;code&gt;setDaemon&lt;/code&gt;)?
Consider &lt;code&gt;Popen&lt;/code&gt; or &lt;code&gt;file()&lt;/code&gt; -- the &lt;a href=&quot;http://www.python.org/dev/peps/pep-0020/&quot;&gt;one, obvious way&lt;/a&gt;
that Python follows is &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization&quot;&gt;resource instantiation is acquisition&lt;/a&gt;.
Why introduce useless states in the lifetime of the object? You just lay the ground for
unexpected code flows that may result in bugs.&lt;/p&gt;

&lt;p&gt;What can you do with an unstrarted thread? Pass it on to someone else, who will start it. That's
a very general concept, called &lt;a href=&quot;http://docs.python.org/library/functools.html#functools.partial&quot;&gt;partial application&lt;/a&gt;,
or &lt;a href=&quot;http://en.wikipedia.org/wiki/Currying&quot;&gt;currying&lt;/a&gt;. Python has lambda functions and &lt;code&gt;partial&lt;/code&gt;,
but Java doesn't... The easiest way to create such &quot;deferred&quot; objects is to add &quot;deferredness&quot;
as an internal state of the object -- it's a common Java practice, uncalled for in Python.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;It's funny how the &lt;em&gt;limitations&lt;/em&gt; of Java were ported to Python as well, and made the implementation
ugly -- it's a classical case of &quot;I don't want to think, let's just copy an existing solution&quot;.
Luckily, it seems to be a thing of the past -- it only entered stdlib in the old days, before the
community had a clear notion of what &lt;em&gt;being pythonic&lt;/em&gt; meant. But still, Javaism of all degrees is
widespread, especially in corporate-developed large-scale projects (Zope and twisted, to name a
few, but naturally closed-source corporate-internal projects are even more susceptible).&lt;/p&gt;

&lt;h2&gt;Exceptions&lt;/h2&gt;

&lt;p&gt;Java had a good insight (that they most likely stole from some other language) in that exceptions
are part of a function's signature. Just like a function takes an argument of type T1 and returns a
result of type T2, it also has &quot;side channels&quot; through which it can produce results, known
as exceptions, which should be documented and checked as well.&lt;/p&gt;

&lt;p&gt;The problem is, trying to foresee everything that might ever go wrong is a futile attempt, and
even Java itself makes two exceptions (no pun intended): &lt;code&gt;Error&lt;/code&gt;, for unrecoverable exceptions
(such as &lt;code&gt;VirtualMachineError&lt;/code&gt;), and &lt;code&gt;RuntimeException&lt;/code&gt;, for exceptions that may always occur
(such as &lt;code&gt;NullPointerException&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The fundamental idea is correct, but it was bound to fail: first, because people are lazy,
but most importantly, because trying to predict all unexpected, future edge cases is absurd.
For instance, suppose you're implementing an interface that stores data (say, in files), so you
might find yourself implementing a signature such as &lt;code&gt;void write(byte[] data) throws IOException&lt;/code&gt;.
Now suppose your implementation uses a third-party database engine, that throws &lt;code&gt;MySQLException&lt;/code&gt;.
For obvious reasons, &lt;code&gt;MySQLException&lt;/code&gt; does not derive from &lt;code&gt;IOException&lt;/code&gt;, and there's nothing
you can do about it, as both the interface and the DB engine are given to you. You're now faced
with three options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Translate &lt;code&gt;MySQLExceptions&lt;/code&gt; into &lt;code&gt;IOExceptions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;When designing interfaces, always declare the most general exception in &lt;code&gt;throws&lt;/code&gt; clauses&lt;/li&gt;
&lt;li&gt;When implementing libraries, always derive your exceptions from an unchecked exception
(&lt;code&gt;RuntimeException&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;In short -- you need to &lt;strong&gt;find a workaround&lt;/strong&gt; and by-pass the compiler's checking. This
essentially means that &lt;code&gt;throws&lt;/code&gt; should have served for documentation-only purposes, where the
compiler might produce (suppressible) &lt;em&gt;warnings&lt;/em&gt; should you not follow conventions. It's more of
a semantic property, like idempotence or thread-safety... you may state it in your Javadoc,
but you wouldn't expect the compiler to &lt;em&gt;enforce&lt;/em&gt; that (not in a language like Java, anyway).&lt;/p&gt;

&lt;p&gt;I'd guess most people agree that the second and third options are &quot;inherently bad&quot;, but opinions
diverge on the first one. I will try to show that &lt;em&gt;exception-wrapping&lt;/em&gt; (translating exceptions)
is just as bad -- at least when it comes to Python. We'll cover this in &lt;strong&gt;part 2&lt;/strong&gt;.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>RPCs, Life and All</title>
   <link href="http://tomerfiliba.com/blog/RPCs-Life-And-All"/>
   <updated>2012-06-25T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/RPCs-Life-And-All</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-06-25-duckface.jpg&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A colleague of mine, &lt;a href=&quot;https://twitter.com/#!/gavrieph&quot;&gt;Gavrie Philipson&lt;/a&gt;, has written an
interesting blog post titled &lt;a href=&quot;http://philipson.co.il/blog/2012/06/20/why-i-dont-like-rpc/&quot;&gt;Why I Don't Like RPC&lt;/a&gt;,
in which he explains that transparent/seamless RPCs (a la &lt;a href=&quot;http://rpyc.sf.net&quot;&gt;RPyC&lt;/a&gt;) make
debugging and reasoning efforts hard. For instance, you might work with an object (a proxy) that
points to an object on the server process, which, in turn, is also a proxy that points to an
object on yet another server process. Ideally, your local code shouldn't be aware of the
complexity (&quot;number of hops&quot;) or the details -- but that's not always the case.&lt;/p&gt;

&lt;p&gt;Well, he won't allow commenting on his blog, so I'm forced to formulate my response here&amp;nbsp;:)
Naturally, I'm biased about this subject, but I thought if I'm on it, why not also cover the
broader aspects of the issue... However, it just kept getting longer and longer, until I got this
behemoth of a blog post, so I'm attaching a &lt;strong&gt;TL;DR info box&lt;/strong&gt;:&lt;/p&gt;

&lt;ul class=&quot;notebox&quot;&gt;
&lt;li&gt;Transparent object proxying is only the logical way to extend RPCs to duck-typed languages&lt;/li&gt;
&lt;li&gt;Asking for a &lt;em&gt;clear distinction&lt;/em&gt; between local and remote objects ultimately means you're
  asking for a statically-typed language; it doens't make sense to ask for it in python&lt;/li&gt;
&lt;li&gt;Network programming is hard, and it's a pity we still work at the socket level; we should 
  strive for a decent fifth layer that would eliminate all the unnecessary complexity&lt;/li&gt;
&lt;li&gt;General-purpose RPCs are the &lt;strong&gt;right primitive&lt;/strong&gt; over which network programming should be
  abstracted: it's the missing fifth layer, which every network application reinvents&lt;/li&gt;
&lt;li&gt;HTTP is a half-baked, broken alternative to a fifth layer; I'm glad ZeroMQ and others are
  starting to loosen its grasp.&lt;/li&gt;
&lt;li&gt;RPyC &lt;strong&gt;can&lt;/strong&gt; be used efficiently and correctly, it's not an impossible feat. Also, a show 
  case of how I'm using RPyC to build a testing environment.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;On Transparency&lt;/h2&gt;

&lt;p&gt;Gavrie's main point is that transparency opens the door to (possibly) unplanned and undesired
complexity. When it's &quot;too easy&quot; to spread around, you might be tempted to (or even unknowingly
end up with) creating over complicated (and cyclic) dependency graphs, stretching over several
processes / machines, where it would be quite a feat to see the whole picture. The nice thing is,
when it works - it just works (and you're happy with your design), but when it fails, you want
to be able to untangle the mess. As he puts it:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;“Seamless” RPC encourages the writing of spaghetti code, because it’s so easy to mix local
and remote code. This makes it deceptively easy to write distributed code without thinking
about the design of the API and about which parts should reside on each side of the connection&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;An ideal remoting solution, according to Gavrie,&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;[...] should make the distinction between local code and remote code crystal
clear to the developer.&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;On Duck Typing&lt;/h2&gt;

&lt;p&gt;I agree with the key points in Gavrie's argument, and I can assert that &lt;em&gt;debugging RPyC itself&lt;/em&gt;,
during development, is highly deceptive (hint: never &lt;em&gt;print&lt;/em&gt; an object...) and calls for
all sorts of creative solutions. But then again, you &lt;em&gt;are&lt;/em&gt; using a &lt;strong&gt;duck-typed, interpreted
language&lt;/strong&gt;. The &quot;if it walks like a duck&quot; phrase will soon make a more dramatic entrance,
but for the time being, suffice it to say we only care for the &lt;em&gt;runtime behavior&lt;/em&gt; of an object.
Any object that I can &lt;code&gt;.read()&lt;/code&gt; from or &lt;code&gt;.write()&lt;/code&gt; to, is a &quot;file concept&quot;, and thus code
should be compatible with any object that &quot;adheres to this concept&quot;.&lt;/p&gt;

&lt;p&gt;A &quot;file&quot; might be an on-disk file, an in-memory byte stream, a mock object used for testing,
or a SCSI device located on a remote storage array. &lt;strong&gt;The only natural way to extend the notion
of duck-typing to RPCs is via transparent object proxying&lt;/strong&gt;. If &lt;code&gt;open()&lt;/code&gt; doesn't differentiate
between local and remote (NFS/SMB) files, and if my code doesn't care for anything other than
&lt;em&gt;runtime behavior&lt;/em&gt;, such a &quot;file concept&quot; might as well be a proxy object that points to a file
object on a remote machine. It's only logical... in fact, it's taking duck typing to its
full potential!&lt;/p&gt;

&lt;h2&gt;On Types&lt;/h2&gt;

&lt;p&gt;Gavrie wants the RPC framework to &quot;make the distinction between local code and remote code crystal
clear to the developer&quot; -- well, Garvie might not have thought about it thoroughly,
but what he's actually asking for is a &lt;strong&gt;static type system&lt;/strong&gt;. Types allow us to &lt;em&gt;make distinctions
between objects&lt;/em&gt;; they partition the &quot;universe of data&quot; into disjoint subsets that we can
reason about: integers, floats, strings (to name a few). We can then group several types together,
under the notion of a &lt;em&gt;type class&lt;/em&gt;. For instance, floats and integers, albeit inherently different,
both belong in the type class &lt;em&gt;number&lt;/em&gt;, which provides us with additional operational semantics
(like ordering relations, etc.).&lt;/p&gt;

&lt;p&gt;We use types to partition the universe, because different &quot;things&quot; have different semantics
and it doesn't make sense to mix them together (modulo converting data of one type to data of
another type). In fact, we normally want to &lt;em&gt;prevent&lt;/em&gt; ourselves from mixing incompatible objects
(be it integers and strings, or local and remote references) -- that's why we have type systems,
and catch type mismatches at compilation time.&lt;/p&gt;

&lt;p&gt;When you require a &lt;em&gt;clear distinction&lt;/em&gt; between objects, it means you're after a &lt;strong&gt;statically typed
language&lt;/strong&gt;; otherwise, you might as well just come up with a &lt;em&gt;naming convention&lt;/em&gt;, where all
variables that (might) refer to a remote object start with &lt;code&gt;rem_&lt;/code&gt;. But if you want
this distinction to &lt;em&gt;propagate&lt;/em&gt; throughout the code, it must be &lt;em&gt;enforced&lt;/em&gt; by a compiler;
if you want to keep yourself in the duck-typed world, it doesn't make sense.&lt;/p&gt;

&lt;p&gt;Duck-typing (from a type-theoretic perspective) is like saying there's only a
&lt;a href=&quot;[http://www.haskell.org/haskellwiki/Why_Haskell_matters&quot;&gt;single data type&lt;/a&gt;, which covers the
entire universe; all checking is deferred to runtime, in which case it might (1) work, (2) fail,
(3) silently cause corruption (as in a &lt;code&gt;TextToSpeech&lt;/code&gt; instance, which may as well expose
a &lt;code&gt;.read()&lt;/code&gt; method, but it surely won't do what we expect the &quot;file concept&quot; to do).&lt;/p&gt;

&lt;p&gt;So asking for a &quot;clear distinction&quot; in a duck typed language is simply out of the question.
What we can ask for is distinction in the level of APIs; for instance,
&lt;code&gt;write_local_file(filename)&lt;/code&gt; vs. &lt;code&gt;write_remote_file(filename)&lt;/code&gt;, but that breaks the
&quot;spirit of duck-typing&quot;, where objects are no longer considered equal (even though they provide
the desired runtime behavior). It's like pointing out the ugly ducklings and making fun of them...
that's not cool.&lt;/p&gt;

&lt;p&gt;Just to contrast, an RPyC-like library for Haskell would expose remote references as a distinct
type class. You could have a function like &lt;code&gt;remoteSum :: (Num a) =&amp;gt; Remote [a] -&amp;gt; a&lt;/code&gt;, which
takes a reference to a remote list of &lt;code&gt;a&lt;/code&gt;'s, and returns its sum. Because it &lt;em&gt;knows&lt;/em&gt; it
operates on remote lists, it might be able to &quot;move&quot; the actual summation remotely, instead of
sending the entire list over the network, item by item. I think this qualifies for a
&quot;crystal clear distinction&quot;, but of course, that's not what the snake teaches.&lt;/p&gt;

&lt;h2&gt;On Networks&lt;/h2&gt;

&lt;p&gt;It seems to me that people find it easy to abstract all sorts of concepts, as long as they don't
concern networks. When there's network involved, they tend to want to &quot;get a feel of the wire&quot;...
so they might use HTTP instead of the NIC directly, but they won't take the next step and treat
network resources as first class objects. There's always a gap, between what's &lt;em&gt;here&lt;/em&gt; and what's
&lt;em&gt;there&lt;/em&gt;, and we're still too aware of the &lt;em&gt;how to get there&lt;/em&gt; details... a gap that should have
been bridged over long ago.&lt;/p&gt;

&lt;p&gt;As I see it, it stems from two primal fears, so to speak: networks are &lt;em&gt;hard&lt;/em&gt; (timeouts, routing,
DNS, reconnects, authentication, compression, tunneling, round-trip time, ...) and &lt;em&gt;unreliable&lt;/em&gt;.
As far as unreliability goes, there's not much you &lt;em&gt;can&lt;/em&gt; do about it; after all, the server is
a process like any other, and may crash at any point of time. If that's not enough, the remote
machine might freeze or reboot. But then again, your local machine might kernel-panic or just
go down with a power failure, losing any unflushed data... but that's life. On the other hand,
it seems to me that overall (hardware?) unreliability rates are going down with time, which is
a promising outlook.&lt;/p&gt;

&lt;p&gt;The &quot;hardness&quot; of network programming, on the other hand, is something we &lt;em&gt;can solve&lt;/em&gt;. Good network
programming is hard, there's no question there, but for some reason, instead of solving the
problem once of for all in a generic manner, it seems that every protocol / network-oriented
application seeks to start at square one. Of course, done this way, it only handles the aspects
it finds relevant... doing network programming at the socket level is analogous to rewriting
the kernel for every desktop application. It doesn't make sense.&lt;/p&gt;

&lt;p&gt;I've started (and abandoned) an ambitious project called &lt;a href=&quot;http://tomerfiliba.com/projects&quot;&gt;layer5&lt;/a&gt;,
which aimed to concentrate all the network-related sorcery in a single place, so that programs on
top of it wouldn't have to care. It originated from my frustration with network programming in
general (and in RPyC in particular)... things like handling timeouts, reconnects, authentication,
negotiation, compression, serialization, load distribution, caching, error reporting -- you name it.&lt;/p&gt;

&lt;p&gt;Just to show-off a couple of ideas, consider a socket connection being dropped for some reason:
if the network layer knew how to reconnect and resume the session, or automatically resend a
request after some timeout (all configurable, of course), there would be no need for the
application to be aware of anything. And, once you &quot;lift&quot; your code up from the socket layer,
you can enable things like &quot;moving targets&quot;, where you may switch an IP address (wifi/3G) and the
connection will just &quot;follow you&quot;; the &lt;em&gt;session&lt;/em&gt; would not be bound to a &quot;physical endpoint&quot;.
These are just some of the issues that layer5 attempted to solve.&lt;/p&gt;

&lt;h2&gt;On RPCs&lt;/h2&gt;

&lt;p&gt;Let me make a bold claim: &lt;strong&gt;everything is RPC&lt;/strong&gt;. So, by &lt;em&gt;everything&lt;/em&gt; I mean &lt;em&gt;virtually all&lt;/em&gt;
connection-oriented network protocols (e.g., excluding broadcasts / multicasts / streaming),
and I take &lt;em&gt;RPC&lt;/em&gt; to its broadest sense: an RPC is any message-oriented protocol in which one side
makes requests that the other side fulfills: basically invoking a remote function. Naturally,
in order to convey a message, the RPC imposes a serialization format, and in order to tell success
from failure, it must also define &quot;return codes&quot;. &lt;strong&gt;Note:&lt;/strong&gt; I've been planning to write about this
topic for a very long time, but never got to it; it surely deserves a post of its own, but
until that happens, please consider this a &quot;briefing&quot;.&lt;/p&gt;

&lt;p&gt;As a case study, let's examine HTTP: there are 4 (or so) &lt;em&gt;methods&lt;/em&gt;: &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;
and &lt;code&gt;DELETE&lt;/code&gt;. Each such &lt;em&gt;method&lt;/em&gt; takes &lt;em&gt;arguments&lt;/em&gt;, like the URL, cookies, accept-encoding,
etc. Some of them are required, some are optional; some pertain to the transport layer
(content-length, compression, timeouts) while others to the method itself (URL, cookie, ...).
It also defines &lt;em&gt;status codes&lt;/em&gt; for distinguishing errors from success (and again, it mixes
transport-layer errors like &lt;em&gt;redirect&lt;/em&gt; with method-level ones like &lt;em&gt;not found&lt;/em&gt; or
&lt;em&gt;internal server error&lt;/em&gt;). It also defines a (very loose) serialization format for encoding
the method's arguments (newline-separated key-value strings) and the payload
(&lt;code&gt;multipart/form-data&lt;/code&gt;)... So, from an RPC point of view, HTTP is a service that provides 4
functions (&lt;em&gt;methods&lt;/em&gt;), whose signature is something like &lt;code&gt;(url, formdata = None, **kwargs)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another example is &lt;code&gt;tenlet&lt;/code&gt; -- it basically provides a function whose signature
is &lt;code&gt;void write(char ch)&lt;/code&gt;; when you type, &lt;code&gt;write&lt;/code&gt; is invoked for each key stroke. Aside from
sending characters, telnet also provides all sorts of &lt;em&gt;negotiation&lt;/em&gt; options or &lt;em&gt;commands&lt;/em&gt;, like
&lt;code&gt;bool set_binary()&lt;/code&gt;, &lt;code&gt;void set_terminal(string)&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;As with most &lt;strong&gt;ad-hoc RPC&lt;/strong&gt; protocols, the two we've examined make horrible design choices like
mixing transport-layer options with &quot;business logic&quot; (HTTP) or sending control in-band with the
data (telnet), where a mere &lt;code&gt;\xFF&lt;/code&gt; character in the stream marks the beginning of a command,
so anyone can (maliciously or accidentally) inject commands into the stream. Yet another pitfall
of these protocols is, they begin small, targeting a specific task, but if they're successful,
they grow to &lt;a href=&quot;http://www.telnet.org/htm/dev.htm&quot;&gt;incorporate&lt;/a&gt; many unrelated things, like
encryption and proxy support... as if security is something you sprinkle on top.&lt;/p&gt;

&lt;p&gt;The main point I'm trying to make here is this: &lt;strong&gt;virtually all protocols are basically
degenerate forms of RPC&lt;/strong&gt;. To paraphrase &lt;a href=&quot;http://en.wikipedia.org/wiki/Greenspun's_tenth_rule&quot;&gt;Greenspun&lt;/a&gt;,
all sufficiently complicated network protocols end up redoing compression, security, authentication,
framing, serialization, negotiation / versioning, discovery, you name it (&lt;em&gt;Filiba's Eleventh Rule&lt;/em&gt;).
This observation has brought me to the conclusion that doing network programming at the
&quot;byte level&quot; is wrong, and that a &lt;strong&gt;general-purpose RPC layer&lt;/strong&gt; is the &lt;strong&gt;right primitive&lt;/strong&gt; for this.&lt;/p&gt;

&lt;p&gt;A general purpose RPC would be &lt;em&gt;language-agnostic&lt;/em&gt;, support only simple by-value types, such
as strings, integers and lists (anything more complex can be built on top of that). If would also
make no assumptions on how remote functions operate, if would only care for their signature.
You can think of it as a more structured message-passing protocol, where you replace the notion
of &quot;message codes&quot; by &quot;function names&quot;. This way, it's easy to see that one can straight-forwardly
emulate any message-passing protocol or more advanced RPC, over this layer. Heck, it's f***ing
2012, I want to &lt;code&gt;GET(&quot;/index.html&quot;, Agent=&quot;Chrome&quot;)&lt;/code&gt;, not formulate &lt;code&gt;\r\n&lt;/code&gt;-separated strings or
care about XML/JSON.&lt;/p&gt;

&lt;p&gt;Layer5 (mentioned in the previous section) was to expose such a generic RPC, upon which
applications would base their protocols. You could always just implement a
&lt;code&gt;bytes send(bytes data)&lt;/code&gt; RPC (over which would continue to pass your byte-level messages),
or implement a more semantic interface -- your choice. Either way, you'd benefit from layer5's
handling of reconnects, authentication, and the rest of the list.&lt;/p&gt;

&lt;h2&gt;On HTTP&lt;/h2&gt;

&lt;p&gt;Truth is, we sort-of already have such a &quot;general purpose&quot; layer 5 protocol, called HTTP. By a
strange twist of fate, HTTP has become the de-facto application layer of choice, over which all
kinds of protocols now operate. And we've managed to hide the gruesome details of HTTP under
programmer-friendly libraries and APIs, so we are in a &quot;better shape&quot; now. Yet HTTP is such a
&lt;strong&gt;miserable choice&lt;/strong&gt; for this purpose (hence abominations like
&lt;a href=&quot;http://en.wikipedia.org/wiki/WebSocket&quot;&gt;Websockets&lt;/a&gt; arose), and we all pay the price
(programmatically-speaking, but also in the sense of network bandwidth, CPU time and electricity
bills).&lt;/p&gt;

&lt;p&gt;In my opinion, HTTP owes its success to another misfortunate happening - &lt;em&gt;firewalls&lt;/em&gt;. In the days
of yore, people thought they could eliminate threats simply by blocking all TCP ports, except
for safe/trusted ones. HTTP was considered safe, as it only transfered &quot;hypertext&quot;, so all
firewalls allowed port 80 traffic by default. This fact has led to many protocols being designed
to work on top of HTTP, to be firewall-friendly... which meant firewalls no longer served the
purpose for which they were conceived: blocking ports was not enough, so firewalls had to become
&lt;em&gt;content-aware&lt;/em&gt; anyway. Long story short -- we've only managed to push the problem one level up:
instead of solving it in the forth layer, we now do it in the application layer... no matter what
the port number is.&lt;/p&gt;

&lt;p&gt;However, this initial edge that HTTP had, helped in making it the de-facto transport layer of
choice, which of course had a snowball effect. I'm only happy to see competing protocols like
&lt;a href=&quot;http://www.zeromq.org/&quot;&gt;ZeroMQ&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol&quot;&gt;AMQP&lt;/a&gt;
are starting to take some market share. Down with HTTP!&lt;/p&gt;

&lt;h2&gt;On RPyC&lt;/h2&gt;

&lt;p&gt;Coming back to Gavrie's post, he brings up two additional points. The first:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;In addition, its performance can quickly deteriorate: Objects are being serialized back and
forth all the time, and tens of implicit network round-trips introduce latency all around the code.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Performance is a tricky thing. First, RPyC is mostly ever used on local, secure networks, where
latency and round-trip time (RTT) are low -- so unless you do something really flawed, you shouldn't
experience noticeable degradation. Second, the only places that do suffer from RTT are tight-loops,
and to that end, RPyC &lt;a href=&quot;http://rpyc.sourceforge.net/api/utils_classic.html#rpyc.utils.helpers.buffiter&quot;&gt;already has solutions&lt;/a&gt;.
And thirdly, transparency (like any form of abstraction) hides the underlying complexity, which
means you won't be able to optimize all the way. RPyC makes a choice for simplicity and pythonicity
every time, at the expense of performance.&lt;/p&gt;

&lt;p&gt;From my many years of using RPyC, I must say I've never experienced performance &lt;strong&gt;issues&lt;/strong&gt; that
didn't originate from the use of threading and locks in python, or really bad code. And if the times
are tough, you can always apply lightweight optimization techniques, such as locally &quot;caching&quot;
remote objects that were obtained through a series of lookups, in variables (e.g.,
&lt;code&gt;myfunc = w.x.y.z.myfunc&lt;/code&gt;)... it's normally not that hard. I'm sure Gavrie has experienced
performance issues with RPyC, but I can hardly imagine it could not be solved by reasonable
amounts of such refactoring.&lt;/p&gt;

&lt;p&gt;Which brings us to the last point Gavrie makes:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;I don’t like RPC, especially not stateful RPC that supports access of remote objects by reference&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I hope we already agreed that a general-purpose RPC is equivalent (if not better than) to any
&quot;normal&quot; network protocol, so it's really not RPCs that Gavrie hates but stateful / object-proxying
sessions. This invites another, rather philosophic, question: what is &lt;em&gt;state&lt;/em&gt;? What does it mean
that a protocol is &lt;em&gt;stateless&lt;/em&gt;? I'd guess philosophies like &lt;a href=&quot;http://en.wikipedia.org/wiki/REST&quot;&gt;REST&lt;/a&gt;
come to mind, but that's just a buzzword. From the broadest Turing-machine perspective, if REST
or any other protocol were truly stateless, they would have no &lt;em&gt;effect&lt;/em&gt; on the world and thus would
be of little significance (they'd be &lt;em&gt;read-only&lt;/em&gt; protocols). Just to stress this point --
&lt;code&gt;PUT/POST&lt;/code&gt;-ing to a RESTful interface, adding/altering a record in a database table, is clearly
&lt;em&gt;stateful&lt;/em&gt;: you changed the state of the DB.&lt;/p&gt;

&lt;p&gt;Therefore, these buzzword-rich protocols boast themselves with the term &lt;em&gt;stateless&lt;/em&gt;, while they
mean something very different. In lack of a better term, I'd use &lt;strong&gt;atomicity, durability,
and reboot-ability&lt;/strong&gt; -- which we'll discuss next. And just a last bit of REST: REST has a notion
of idempotency, as GET requests for the same URI should always return the same result (but that's
not guaranteed). Anyway, the &lt;a href=&quot;http://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot;&gt;CRUD model&lt;/a&gt;
which REST employs is quite limited and fits only so many real-life problems (many other problems
can be &lt;em&gt;reduced&lt;/em&gt; to CRUD, but I don't suppose people would consider this the &quot;right way&quot;).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Atomicity&lt;/em&gt; and &lt;em&gt;durability&lt;/em&gt; come from the &lt;a href=&quot;http://en.wikipedia.org/wiki/ACID&quot;&gt;ACID&lt;/a&gt; philosophy of
databases, and are granted to you freely, assuming you use a DB (who doesn't?). They basically mean
that a transaction either fully happens (and then its permanently stored), or nothing happens
(so that no partial results may exist). Reboot-ability is a term I just made up, and it means
your server might crash and be restarted, or your entire lab might burn away, and the client
shouldn't be able to detect any difference (other than temporal unavailability, which may be
compensated for by a cluster). Inherently, it means you don't trust your server to survive over
long periods of time, and therefore prefer to make it (the server &lt;strong&gt;process&lt;/strong&gt;) stateless.
In effect, it means the server will never make &quot;changes to the world&quot; outside of DB transaction,
so that a failed transaction could be rolled back, and a new server process could resume where the
previous one failed. But note the difference: &lt;strong&gt;the server process is stateless, not the protocol&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;HTTP originally was a connection-less protocol (albeit over TCP), where each request was treated
separately from the rest and there was hardly any notion of a session. This meant that every
request had to carry along with it any state information it required. In order to prevent requests
from growing wildly in size and choking the network, cookies were invented -- which meant the
server had to store session data, and the cookie was only a key. This already dents the notion
of statelessness, and nowadays, things like websockets break it completely.&lt;/p&gt;

&lt;p&gt;RPyC, on the other hand, has a clear notion of a &lt;em&gt;session&lt;/em&gt;: on each end of the the connection
there's a dictionary of objects referred to by the other side. This means that should a connection
drop, there's little chance of restoring the lost session: the dictionaries are lost, and all
proxies would be invalidated.&lt;/p&gt;

&lt;p&gt;But all is not lost: if you only need references to serializable objects, you might as well keep
this dictionary as a DB table. Since the data, including object IDs, would not be lost when the
server gets restarted, resuming a dropped session is easy. So, if you could live with limited
functionality, you can be backed by a DB -- but it's not that HTTP offers a better solution.
At least keep your code pythonic and not full of HTTP curses.&lt;/p&gt;

&lt;p&gt;Another alternative, which I'll demonstrate in the next section, is making the changes directly
&quot;in the real world&quot;: instead of &lt;em&gt;storing&lt;/em&gt; state, make the changes on long-living entities, and
then read the info back from them. This way, you're always synchronized, and should you be
restarted, you'll never use stale data.&lt;/p&gt;

&lt;h2&gt;On Testing&lt;/h2&gt;

&lt;p&gt;I'm working now on a testing framework of quite a complicated nature: first, it serves as a
resource-allocator for hosts and other testing equipment; second, in order to run tests, it must
create a suitable environment for them. But this is where it gets fun: in order to do set up the
environment, I must use the utilities that I set out to test... because that's exactly what they
do. Chicken and egg, anybody?&lt;/p&gt;

&lt;p&gt;After a couple of days to toying with it, I settled for the following architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tests are written normally using &lt;code&gt;unittest&lt;/code&gt;, but they also make use of a little module (8 LoC
or so) that provides them with a means to connect to the resource allocator; this module
basically hides the details of setting up an RPyC connection (as the server is well known, etc).&lt;/li&gt;
&lt;li&gt;The resource allocator exposes a simple service, with methods like &lt;code&gt;get_system(version = 17)&lt;/code&gt;.
It collects the information about the systems from a third-party service and caches it in-memory,
so finding a matching system is quick and efficient. Basically, the resource allocator only
takes care of distributing systems randomly (we do want to allow for two tests to run on the
same system, but wish to avoid unnecessary contention).&lt;/li&gt;
&lt;li&gt;The object returned by &lt;code&gt;get_system&lt;/code&gt; is an instance of a peculiar class called
&lt;code&gt;HostViewOfSystem&lt;/code&gt;. It basically represents a how the host (running the test) views the system
that's been allocated to it, and it has methods like &lt;code&gt;get_resource_from_system()&lt;/code&gt; that look
for an unused resource (or create one) and take care of &lt;em&gt;making it usable by the host&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;There are quite a few details, but I hope I managed to make the design clear. On the other hand,
it doesn't seem particularly interesting -- until we get to the last bullet-point -- making the
resource usable by the host. In order to do that, the server (resource allocator) creates a
temporary directory on the host, onto which it copies (over RPyC) several python packages that
are required for the task. It then fires up a new RPyC server on the host, and sets its
&lt;code&gt;PYTHONPATH&lt;/code&gt; to this temporary location. This RPyC server is based on the fresh-from-the-oven
&lt;code&gt;OneShotServer&lt;/code&gt;, which is capable of serving a single client and then quits. The server chooses
a random port and reports it over stdout, to the resource allocator, who then connects to it.
Then, the &lt;code&gt;HostViewOfSystem&lt;/code&gt; object is given a reference to the newly created RPyC service,
and it uses it to manipulate the host machine in order to set up the environment. Here's a sketch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;+---Test Host---+            +---ResAlloc Server---+
|               |            |                     |
|  -----------  |  .-----------&amp;gt; HostViewOfSystem  |
|  | Test    |____/          |     |               |
|  | process |  |            |     |               |
|  -----------  |     _____________/               |
|               |    /       |                     |
|  -----------  |   /        |                     |
|  | Newly   &amp;lt;-----*         |                     |
|  | started |  |            |                     |
|  | RPyC    |  |            +---------------------+ 
|  | server  |  |
|  -----------  |
|               |
+---------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This quite tiresome setup actually takes only ~30 lines of code (and around one second to build),
and it allows the tested utilities to rely on &lt;em&gt;stable versions&lt;/em&gt; of themselves. The stable versions
are fetched from the resource allocator server, thus we make absolutely no assumptions on the
state of the host. Moreover, when we &quot;allocate&quot; a resource for a specific test, we &lt;em&gt;mark&lt;/em&gt; the
resource on the system as &quot;in used&quot;: it's neither stored in-memory, nor in a DB -- it's marked
directly on the resource, as metadata. This way, if the resource allocator is restarted,
no state is lost -- the new instance will read the most up-to-date state from the &quot;real world&quot;.
There -- a semi-stateless testing framework based on RPyC... and now I go to bed.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Reed-Solomon Codec</title>
   <link href="http://tomerfiliba.com/blog/ReedSolo"/>
   <updated>2012-06-08T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/ReedSolo</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-06-08-qr.png&quot; title=&quot;Reed Solomon for coders&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Some Background&lt;/h2&gt;

&lt;p&gt;I'm working on an image processing project for the university, whose purpose is to embed
(an extract) a &lt;em&gt;print-scan resilient watermark&lt;/em&gt; into an image. This project has (sadly) gotten me
acquainted with Matlab, from which I quickly ran way into the friendlier realms of
&lt;a href=&quot;http://www.scipy.org/&quot;&gt;Scipy&lt;/a&gt; and friends (&lt;a href=&quot;http://scikits-image.org/&quot;&gt;Skimage&lt;/a&gt; rocks, by the way).
I must say I really learned to appreciate the Scipy/Numpy gang in the last two weeks :)&lt;/p&gt;

&lt;p&gt;If it wasn't already obvious, it's time to admit I'm a n00b when it comes to signal processing and
applied math in general. I know the Fourier transform in broad terms, and have heard of
&lt;a href=&quot;http://en.wikipedia.org/wiki/Discrete_cosine_transform&quot;&gt;discrete cosine transform&lt;/a&gt;
and &lt;a href=&quot;http://en.wikipedia.org/wiki/Wavelet&quot;&gt;wavelets&lt;/a&gt; some time ago... but it's not my cup of tea,
to say the least. Luckily for &lt;strong&gt;clueless people&lt;/strong&gt; like me, Matlab (and its kin) enables us
to summon the dark powers of mathematics, without ever having to know what we're doing. Hurrah!&lt;/p&gt;

&lt;p&gt;So I'm DFT'ing, DCT'ing and DWT'ing like a pro, embedding my watermark using CDMA/spread-spectrum
techniques in the frequency domain, and then inverting the process... and all I know is
I'm supposed to keep myself in the mid-frequency range, i.e., in a certain region of the matrix.
Math for n00bs.&lt;/p&gt;

&lt;p&gt;My original idea was to take a string, encode it as a &lt;a href=&quot;http://en.wikipedia.org/wiki/QR_code&quot;&gt;QR code&lt;/a&gt;,
and then embed this QR image into the host image. I thought it would be a nice shortcut, as it
provided me with a synchronization pattern and error correction out of the box, but it quickly
turned out QR codes generate a payload that's too big for unobservable embedding.
So I set out to find some error correcting code (ECC) library for python, but it proved to be
a really difficult task. I found some packages, most of them are haven't been maintained in over
7 years nows, and all of them make use of extension modules that failed to compile. Then there's
&lt;a href=&quot;http://pypi.python.org/pypi/zfec&quot;&gt;zfec&lt;/a&gt;, but for the life of me, I couldn't figure out how to
use it as a simple encoder/decoder.&lt;/p&gt;

&lt;h2&gt;The Library&lt;/h2&gt;

&lt;p&gt;I almost gave up and resorted to triplicating my payload (at the bit level), and using
majority-selection for each bit, when I came across an &lt;strong&gt;amazing python tutorial&lt;/strong&gt; (with runnable
code) that covers &lt;a href=&quot;http://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders&quot;&gt;Reed Solomon codes and QR in depth&lt;/a&gt;.
I simply extracted the code, added a usable API, wrote some examples and quickly
&lt;a href=&quot;http://pypi.python.org/pypi/reedsolo&quot;&gt;uploaded it to PyPI&lt;/a&gt;, so now there's a pure-python
Reed-Solomon encoder/decoder: &lt;code&gt;pip install reedsolo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The library should support python 2.4-3.2, using strings or bytes. I really can't verify the
correctness of the algorithm (it's beyond me), but it seems to work so I'm fine with it. Here's
a short demo:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;reedsolo&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RSCodec&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RSCodec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;# 10 bytes of ECC will be added to the output, &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                     &lt;span class=&quot;c&quot;&gt;# which allows us to correct up to 5 byte-level errors&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;\x01\x02\x03\x04,\x9d\x1c+=\xf8h\xfa\x98M&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;hello world\xed%T\xc4\xfd\xfd\x89\xf3\xa8\xaa&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;hello world&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xed&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%T&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xc4\xfd\xfd\x89\xf3\xa8\xaa&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;hello world&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now let's add some errors:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;hXXlo worXd&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xed&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%T&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xc4\xfd&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x89\xf3\xa8\xaa&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;     &lt;span class=&quot;c&quot;&gt;# 4 errors - ok&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;hello world&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;hXXXo worXd&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xed&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%T&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xc4\xfd&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;XX&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xf3\xa8\xaa&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;        &lt;span class=&quot;c&quot;&gt;# 6 errors - fail&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;reedsolo.ReedSolomonError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;Could not locate error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It's pure python and highly unoptimized... I think someone acquainted with Numpy a little
more than I am could improve it blindfolded by a factor 10, but even now, on my dinosaur machine,
it encodes a 400kB message in 2.9 seconds and decodes it in 1.9 seconds. I'll drink to that.
By the way, it seems that the library &lt;strong&gt;can only handle messages that are less than 255 bytes
long&lt;/strong&gt;... but then you can simply encode/decode in chunks. I'll include it in later versions.&lt;/p&gt;

&lt;p&gt;I think a good ECC library for python is very useful... if anyone wants to join in on it,
feel free to drop me a line at the comments or just
&lt;a href=&quot;https://github.com/tomerfiliba/reedsolomon&quot;&gt;fork the repo&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Some Notes on RPyC 3.2.x</title>
   <link href="http://tomerfiliba.com/blog/Some-Notes-On-RPyC"/>
   <updated>2012-06-06T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Some-Notes-On-RPyC</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://rpyc.sourceforge.net/_static/rpyc3-logo-medium.png&quot; title=&quot;RPyC logo&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As I said in the previous blog post, I hoped for v3.2.2 to be the last release of the 3.2 line...
Naturally, I was wrong :) Turns out the fix for
&lt;a href=&quot;https://github.com/tomerfiliba/rpyc/issues/76&gt;&quot;&gt;issue #76&lt;/a&gt; was buggy, and I decided to finally
remove the use of excepthooks in favor of taking care of remote traceback chaining in the
exception class' &lt;code&gt;__str__&lt;/code&gt; method itself. The tentative release date for the release is
August 1st, and I really hope to end the 3.2 line here.&lt;/p&gt;

&lt;p&gt;I created a branch called &lt;code&gt;LTS3.2&lt;/code&gt; which will be used only for back-porting bug fixes from
the &lt;code&gt;master&lt;/code&gt; branch, which has now become the development branch of 3.3. I rebased &lt;code&gt;master&lt;/code&gt;
on top of &lt;code&gt;LTS3.2&lt;/code&gt; now, so that the two would have linear histories, which of course resulted
in a forced update, so anyone who was using master for development would now have to do
&lt;code&gt;git fetch origin; git reset --hard origin/master&lt;/code&gt; instead of a simple &lt;code&gt;git pull&lt;/code&gt;.
It's not supposed to happen again, sorry.&lt;/p&gt;

&lt;p&gt;There shouldn't be any more features in v3.2.3, so the development would take place on &lt;code&gt;master&lt;/code&gt;,
from which I'll cherry-pick bug fixes onto LTS3.2. That's all for now...&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>RPyC 3.2.2 Released</title>
   <link href="http://tomerfiliba.com/blog/RPyC-3.2.2"/>
   <updated>2012-06-01T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/RPyC-3.2.2</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://rpyc.sourceforge.net/_static/rpyc3-logo-medium.png&quot; title=&quot;RPyC logo&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is a maintenance release, fixing some issues concerning introspection, &lt;code&gt;ForkingServer&lt;/code&gt;
and signals, IronPython and signals, and SSH on Windows. It also introduces optional logging
of exceptions that occur over the RPyC connection to the server's logger (or any other logger
instance, given in the connection's configuration). The
&lt;a href=&quot;http://rpyc.sourceforge.net/changelog.html&quot;&gt;change log&lt;/a&gt; has more details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is the last release of the 3.2 branch. Future releases (of the 3.3 branch) will
require &lt;a href=&quot;http://plumbum.readthedocs.org&quot;&gt;plumbum&lt;/a&gt;, thus the SSH support will be removed from the
codebase. The next version will also provide &lt;a href=&quot;https://github.com/tomerfiliba/rpyc/issues/81&quot;&gt;zero-deploy&lt;/a&gt;,
which will make RPyC much easier to use. This release is expected in September.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>The Future of Construct</title>
   <link href="http://tomerfiliba.com/blog/Construct-Plans"/>
   <updated>2012-05-16T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Construct-Plans</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-05-16-construct-logo-small.png&quot; title=&quot;Construct&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It's been a long while since I've put time into &lt;a href=&quot;http://construct.wikispaces.com&quot;&gt;Construct&lt;/a&gt;.
I gave up on it somewhere in 2007, right after the release of v2.0... I think I just got bored,
and felt like the library was complete and extensible enough to survive on its own. Of course
I was wrong there, and code-rot had spread all over.&lt;/p&gt;

&lt;p&gt;Luckily for us, &lt;a href=&quot;https://github.com/MostAwesomeDude/&quot;&gt;Corbin Simpson&lt;/a&gt; took up the project in
January of 2011 and has been maintaining it since then. He migrated it to github, changed the
project to use a proper directory structure, fixed lots of bugs, and wrote
&lt;a href=&quot;http://construct.readthedocs.org/en/latest/&quot;&gt;extensive documentation&lt;/a&gt;. Since then, Construct
has been building a solid community and has reached quite a remarkable number of downloads on PyPI.&lt;/p&gt;

&lt;p&gt;All this time, I've been busy with my other projects, but I kept toying with the idea of
&lt;em&gt;Construct 3&lt;/em&gt;. I got some sketches, wrote some early drafts, cleaned up the implementation of
Construct's core... but it's remained a dream. A couple of months ago I decided I'd back-port a
nice feature from Construct 3, called
&lt;a href=&quot;https://github.com/construct/construct/commit/969e5685ce7251af49c9e267a732b63bcea4e278&quot;&gt;this expressions&lt;/a&gt;,
and it has rekindled my interest in the library.&lt;/p&gt;

&lt;h2&gt;&lt;code&gt;This&lt;/code&gt; Expressions&lt;/h2&gt;

&lt;p&gt;One of the goals of Construct 3 was to generate efficient (C/Python) code from construct definitions.
It even worked, to some extent: for instance, see &lt;a href=&quot;http://sebulbasvn.googlecode.com/svn/trunk/ccon/test.py&quot;&gt;this snippet&lt;/a&gt;
that automatically generates &lt;a href=&quot;http://sebulbasvn.googlecode.com/svn/trunk/ccon/moshe.c&quot;&gt;this C-code&lt;/a&gt;.
I had no recollection of this &lt;a href=&quot;https://github.com/MostAwesomeDude/construct/pull/20#issuecomment-5727638&quot;&gt;until I discovered it today&lt;/a&gt;.
Funny.&lt;/p&gt;

&lt;p&gt;Anyway, Construct 2 uses &lt;code&gt;lambda&lt;/code&gt; functions to represent dependencies between constructs, e.g.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;LV&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UBInt8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;length&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;length&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and since this is the case, it's impossible to translate dependencies to C. So I've created the
&lt;code&gt;this&lt;/code&gt; object, which essentially &lt;strong&gt;builds&lt;/strong&gt; an expression tree from native Python expressions.
In order to evaluate the expression, you simply invoke it with a context:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;construct&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((this.x * 2) + 3)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;17&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So now we can replace all &lt;code&gt;lambda ctx: ctx[&quot;foo&quot;]&lt;/code&gt; by the more succinct and readble &lt;code&gt;this.foo&lt;/code&gt; --
the benefits are visually clear -- but they go even deeper than this: since we're no longer
dealing with &lt;strong&gt;black-box&lt;/strong&gt; lambda functions, we can drill down into them and generate the
appropriate (static) code.&lt;/p&gt;

&lt;h2&gt;Construct 2.5&lt;/h2&gt;

&lt;p&gt;I had to do some Construct work recently, and I missed the conciseness of &lt;code&gt;this&lt;/code&gt; expressions,
so I took the time to back-port them to Construct 2. I sent a pull request to Corbin, but he's
a bit too busy to maintain the library on a regular basis now, so he's created a github
&lt;em&gt;organization&lt;/em&gt; and &lt;a href=&quot;https://github.com/construct/construct&quot;&gt;moved the repository there&lt;/a&gt;;
this is where Construct will be developed from now on.&lt;/p&gt;

&lt;p&gt;Tinkering with the old code again got me sentimental, and I started to do some long-awaited
maintenance. I plan to release version 2.5 (note the dramatic shift from 2.06 to 2.5) in the summer
(say August), and here's the list of planned changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding &lt;code&gt;this&lt;/code&gt; expressions&lt;/li&gt;
&lt;li&gt;Dropping &lt;code&gt;construct.text&lt;/code&gt; -- it's always been an experimental feature and it's achingly
inefficient. If you want to parse &lt;strong&gt;grammars&lt;/strong&gt;, you should use
&lt;a href=&quot;http://wiki.python.org/moin/LanguageParsing&quot;&gt;more adequate tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Adding Python 3 support (based on the work of &lt;a href=&quot;https://github.com/MostAwesomeDude/construct/pull/19&quot;&gt;Eli Bendersky&lt;/a&gt;);
the library will support Python 2.5-3.2, using &lt;code&gt;six&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;General cleanups and optimizations&lt;/li&gt;
&lt;li&gt;Closing the &lt;em&gt;wikispaces&lt;/em&gt; site in favor of &lt;em&gt;readthedocs&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Construct 3&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;next big thing(TM)&lt;/em&gt;, &lt;a href=&quot;https://github.com/tomerfiliba/construct3&quot;&gt;Construct 3&lt;/a&gt;, is still far away.
I've got lots of cool ideas, but time is too short (as so is my ability to concentrate on one thing).
Generally, the guiding thought is to &lt;strong&gt;modernize the library&lt;/strong&gt; and make it even yet more compact
and efficient, while removing magic along the way. For instance, because &lt;code&gt;Structs&lt;/code&gt; require their
sub-elements to have a name, and due to the fact keyword-arguments in Python are unordered,
all constructs ended up taking a name argument (even though it's usually meaningless to them,
as in &lt;code&gt;UBInt8(&quot;length&quot;)&lt;/code&gt;). This has given birth to all sorts of bastards like &lt;code&gt;Rename&lt;/code&gt; and
&lt;code&gt;Alias&lt;/code&gt;; from now on, it'll be simpler:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Member&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;length&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UBInt8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Member&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;A second issue is, laying the grounds for &lt;strong&gt;code generation&lt;/strong&gt;, thus converting all dependencies
to use &lt;code&gt;this&lt;/code&gt; expressions, and perhaps even limiting the power of &lt;code&gt;Adapters&lt;/code&gt;. Or at least,
making a clear distinction between the constructs that can be turned into code and those that can't.&lt;/p&gt;

&lt;p&gt;And last but not least, I want Construct 3 to come with a &lt;strong&gt;designer&lt;/strong&gt;, where you would drag-and-drop
constructs, group them in &quot;boxes&quot;, connect them to each other (instead of &lt;code&gt;this.length&lt;/code&gt;, you'd
connect the Bytes' &lt;code&gt;count&lt;/code&gt; field to the source construct), etc. And most importantly, you could
try it out live on a data sample, and see how it breaks it up. I made this sketch here (click to
download the PowerPoint slides) to demonstrate how it might look:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://tomerfiliba.com/static/res/2012-05-16-sketch.ppt&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-05-16-designer.png&quot; title=&quot;Construct Designer&quot; width=&quot;580px&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think it would be very powerful.&lt;/p&gt;

&lt;h2&gt;Closing Words&lt;/h2&gt;

&lt;p&gt;I'm mainly writing this post to inform everyone of Construct's &lt;a href=&quot;https://github.com/construct/construct&quot;&gt;new repository&lt;/a&gt;,
and to &lt;strong&gt;ask for feedback&lt;/strong&gt; on the plans for v2.5... Any thoughts, requests, comments would be
appreciated. Also, if anyone wants to join in (especially with Construct 3 ambitious plans) --
feel free to contact me.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Introducing Plumbum - Shell Combinators</title>
   <link href="http://tomerfiliba.com/blog/Plumbum"/>
   <updated>2012-05-12T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Plumbum</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://plumbum.readthedocs.org/&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-05-12-plumbum.png&quot; title=&quot;Plumbum&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's been a while since I last blogged... sorry! Had a midterm exam, a seminar project to deliver
(an &lt;code&gt;O(n^3)&lt;/code&gt; parser for &lt;a href=&quot;http://acl.ldc.upenn.edu/J/J95/J95-4002.pdf&quot;&gt;Tree Insertion Grammar&lt;/a&gt;),
the routine family festivities of Passover, and this new thing, &lt;em&gt;Plumbum&lt;/em&gt;, that has been keeping
my mind overclocked while I should have been studying for exams and writing seminar papers.
But now that it's out, it's about time I write a little on it.&lt;/p&gt;

&lt;p&gt;So &lt;a href=&quot;http://plumbum.readthedocs.org/&quot;&gt;Plumbum&lt;/a&gt; is something I've toyed with for quite some time now.
In almost any sort of project, there comes a time when you have to write this really simple,
5-liner shell script, just to build your project's artifacts, maybe also upload them to PyPI
or sourceforge (using &lt;code&gt;rsync&lt;/code&gt;), and while you're at it, why not build the project's documentation
as well. Oh, and don't forget to run regression tests before all that, and it would be wise to
also handle some basic command-line options, as you might want to skip uploading to PyPI at times,
or perhaps build on different versions of python... and then you end up with this &lt;strong&gt;monstrous
shell script&lt;/strong&gt; that you wrote (or worse, some former employee wrote) and never want to lay
your eyes on again... At this point to begin hating yourself for not doing it in python,
to begin with.&lt;/p&gt;

&lt;p&gt;But then again, how do you translate &lt;code&gt;find . -name &quot;*.pyc&quot; | xargs rm&lt;/code&gt; or &lt;code&gt;cp */*.py /tmp&lt;/code&gt;
to python-speak? That would take quite a few lines and require importing several modules.
Shell scripts tend to be so short and enchanting... How do we bridge the gap?&lt;/p&gt;

&lt;p&gt;Plumbum was born to fill this very gap: on the one hand, be pythonic (and be backed by strong
libraries), and on the other, make it all as easy and one-liner-ish by nature: use a &lt;strong&gt;real
programming language&lt;/strong&gt;, with a well-behaved object model and high level concepts, to achieve what
you'd normally do in a shell script, retaining the same expressive power and wrist-handiness
of the shell. I call it &lt;strong&gt;shell combinators&lt;/strong&gt;, as it's a pythonic way to mimic shell syntax.&lt;/p&gt;

&lt;p&gt;The library is actually a collection of utilities that I wrote for several separate projects,
and had never got to polish them. Plumbum consolidates them into a single, production-grade
framework. The library provides &lt;strong&gt;local and remote&lt;/strong&gt; program execution, with support for &lt;strong&gt;piping&lt;/strong&gt;
and &lt;strong&gt;IO redirection&lt;/strong&gt;; local and remote file-system &lt;strong&gt;paths abstraction&lt;/strong&gt;; a programmatic
&lt;strong&gt;command-line interface (CLI) toolkit&lt;/strong&gt;, and numerous other utilities.&lt;/p&gt;

&lt;p&gt;For instance,&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plumbum&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plumbum.cmd&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grep&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plumbum.utils&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cwd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;*/*.pyc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cwd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;src&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;*.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;-l&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;num_of_src_lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;-l&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;-l&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])()&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/proc/sys/net/ipv4/ip_forward&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)()&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There's a &lt;a href=&quot;http://plumbum.readthedocs.org/&quot;&gt;short cheat-sheet as well as extensive documentation&lt;/a&gt;
on the project's site, but at this point I'd like to elaborate a bit on the
&lt;a href=&quot;http://plumbum.readthedocs.org/en/latest/cli.html&quot;&gt;CLI toolkit&lt;/a&gt;, as I think it deserves some more
attention.&lt;/p&gt;

&lt;p&gt;The approach of &lt;code&gt;optparse&lt;/code&gt; / &lt;code&gt;argparse&lt;/code&gt; and similar libraries is to build a parser object
and populate it with options in an imperative manner, which I dislike. Plumbum's CLI toolkit offers
a more &lt;strong&gt;declarative&lt;/strong&gt; yet programmatic alternative: An application is defined as a class that
derives from &lt;code&gt;cli.Application&lt;/code&gt;; it may define a &lt;code&gt;main()&lt;/code&gt; method, which serves as the
&quot;entry point&quot; of the application, and any number of &lt;strong&gt;switch-methods&lt;/strong&gt;, meaning, methods that
are invokable from the command-line.&lt;/p&gt;

&lt;p&gt;Switch methods are normal methods, decorated by &lt;code&gt;@switch&lt;/code&gt;, that may take either no arguments
or a single one; for each switch given on the command line, the toolkit will invoke the switch
method that binds it. Similarly, the &lt;code&gt;main()&lt;/code&gt; method is invoked after all switches have been
processed, and it takes all the &lt;em&gt;positional arguments&lt;/em&gt; (i.e., non-switch arguments) that were
given. And last but not least, there are &lt;em&gt;switch attributes&lt;/em&gt;, which are in fact just specialized
versions of switch functions, that store an argument given to the switch in an instance attribute.&lt;/p&gt;

&lt;p&gt;So I've probably only gotten you confused by the terminology at this point, but actually it's
much simpler!&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plumbum&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyHttpServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log_to_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SwitchAttr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;--log-to-file&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;verbose&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;-v&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SwitchAttr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;--mode&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;TCP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;UDP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;TCP&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SwitchAttr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;--port&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65535&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8080&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;-l&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;--load-config&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ExistingFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Loads the given config file&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_parse_config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verbose&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WARNING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MyHttpServer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There, I think it's a lovely example of the expressive power of the CLI toolkit and Plumbum in
general. I hope you'll give it a try, and may you never have to write shell scripts again!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Solving Systems of Linear Equations</title>
   <link href="http://tomerfiliba.com/blog/Linear-System-Solver"/>
   <updated>2012-03-25T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Linear-System-Solver</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-03-25-gauss.png&quot; title=&quot;Carl Friedrich&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Yet another university-related post, but I really enjoyed it so I thought I'd share: for a GUI-
workshop I'm taking, we are given GUI-layout constraints as a system of linear equations, which
we need to satisfy. To make life more interesting, some constraints are constant while some are
parametric. There's no magic here, just some linear algebra combined with Python's overloadable
nature to produce a nice and compact solver for these linear systems.&lt;/p&gt;

&lt;p&gt;Naturally, you present your system as a &lt;em&gt;coefficient matrix&lt;/em&gt;, which is Gauss-eliminated and then
&quot;solved&quot; for a given set of variables. I took the Gauss-Jordan elimination code from
&lt;a href=&quot;http://elonen.iki.fi/code/misc-notes/python-gaussj/index.html&quot;&gt;Jarno Elonen&lt;/a&gt; and modified it to
support MxN matrices (not necessarily square). Here's a simple example of elimination:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eliminate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;( 1.00  -0.00   0.00   6.00)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;( 0.00   1.00  -0.00  -1.00)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;( 0.00   0.00   1.00  -0.50)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But of course a reduced row-echelon matrix is not our final goal - we want to get the variable
&lt;em&gt;assignments&lt;/em&gt;. For this, we have &lt;code&gt;solve()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sol&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;y&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;z&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sol&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;y&amp;#39;: -1.0000000000000004, &amp;#39;x&amp;#39;: 6.0, &amp;#39;z&amp;#39;: -0.4999999999999998}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Modulo precision errors, we get &lt;code&gt;x = 6&lt;/code&gt;, &lt;code&gt;y = -1&lt;/code&gt; and &lt;code&gt;z = -0.5&lt;/code&gt;. If we have more equations than
variables, the &quot;extraneous&quot; equations must be linear combinations of previous ones, or a
contradiction will result. But what if we have less equations than variables? It means we have
some &lt;em&gt;degrees of freedom&lt;/em&gt;... how would we handle that? It's actually simple - instead of being
resolved to constant values, variables will be assigned &lt;em&gt;dependent expressions&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eliminate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;( 1.00   0.00   16.00  -2.00)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;( 0.00   1.00  -6.00   2.00)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sol&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;y&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;z&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sol&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;y&amp;#39;: &amp;lt;BinExpr (2.0 - (-6.0 * z))&amp;gt;, &amp;#39;x&amp;#39;: &amp;lt;BinExpr (-2.0 - (16.0 * z))&amp;gt;, &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    &amp;#39;z&amp;#39;: &amp;lt;FreeVar z&amp;gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;As you can see now, &lt;code&gt;z&lt;/code&gt; is a &lt;em&gt;free variable&lt;/em&gt; and &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are &lt;em&gt;dependent&lt;/em&gt; on it. Of course more
than one variable may be free and some variables may be independent of free variables. Once a value
for &lt;code&gt;z&lt;/code&gt; is known, we can &quot;fully evaluate&quot; the dependent expressions:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;z&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-162.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The code is available on my &lt;a href=&quot;https://github.com/tomerfiliba/tau/blob/850ff76bf59c80cd9eb18100986205276125508e/sadna/linear_solver.py&quot;&gt;github page&lt;/a&gt;.
Note: all numbers are represented as &lt;code&gt;Decimals&lt;/code&gt;, to avoid loss of precision as much as possible,
and I'm using an &quot;epsilon&quot; value of &lt;code&gt;1E-20&lt;/code&gt; to equate numbers to each other (meaning, &lt;code&gt;x == y&lt;/code&gt; iff
&lt;code&gt;abs(x-y) &amp;lt;= epsilon&lt;/code&gt;).&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Easy Syntax for Representing Trees</title>
   <link href="http://tomerfiliba.com/blog/Tree-Syntax"/>
   <updated>2012-03-07T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Tree-Syntax</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-03-07-tag.jpg&quot; title=&quot;TAG trees&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I'm working on a parser for &lt;a href=&quot;http://en.wikipedia.org/wiki/Tree-adjoining_grammar&quot;&gt;Tree Adjoining Grammar (TAG)&lt;/a&gt;
for this seminar I'm taking. TAG is an extension of context-free grammar (CFG) that's more powerful
while still being polynomially-parsable. Anyhow, TAG makes use of &quot;tree production rules&quot; instead of
the &quot;linear&quot; production rules of CFG: instead of &lt;code&gt;S -&amp;gt; NP VP&lt;/code&gt;, you'd have a small tree, the root of
which being &lt;code&gt;S&lt;/code&gt;, having &lt;code&gt;NP&lt;/code&gt; and &lt;code&gt;VP&lt;/code&gt; as its children. Of course these trees can be more than
two-level deep, and they go all sorts of operations such as substitution and adjunction, but that's
for the parser.&lt;/p&gt;

&lt;p&gt;So I needed a compact and (hopefully) readable way to express such trees in my code. At first I
used lots of parenthesis, which was ugly and cumbersome, but then I devised this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NonTerminal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__sub__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__pos__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonterm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nonterm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonterm&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;children&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And here's how you use it:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NonTerminal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;S&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;t1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;e&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;t2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Which represents the following two trees:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# t1:                t2:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#      S                  S &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#      |                / | \&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#      |               /  |  \&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#      e              a   S   b&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                       / | \&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                      /  |  \&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                     c   S*  d&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The peculiar &lt;code&gt;+S&lt;/code&gt; is a way to mark that a leaf node is a &lt;em&gt;foot&lt;/em&gt;, which is part of the semantics TAG
(that's where adjunction takes place). It's represented in the diagram by the more conventional &lt;code&gt;S*&lt;/code&gt;,
but I had to resort to a unary operator in the code. Anyway, I'm not sure if it's a recipe or just
a nice trick, but I thought I'd share this.&lt;/p&gt;

&lt;p&gt;By the way, you can use both &lt;code&gt;__sub__&lt;/code&gt; and &lt;code&gt;__neg__&lt;/code&gt; to achieve things like &lt;code&gt;S-----X&lt;/code&gt; (i.e.,
more than a single &lt;code&gt;-&lt;/code&gt; sign, to allow for better padding), but I tried to avoid too much ASCII art.
I'd love to hear about other such ideas!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>RPyC 3.2.1 Released</title>
   <link href="http://tomerfiliba.com/blog/RPyC-3.2.1"/>
   <updated>2012-03-04T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/RPyC-3.2.1</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://rpyc.sourceforge.net/_static/rpyc3-logo-medium.png&quot; title=&quot;RPyC logo&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is a maintenance release, fixing some minor bugs and resolving some issues with Python 3
compatibility. More on the &lt;a href=&quot;http://rpyc.sourceforge.net/changelog.html&quot;&gt;change log&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Python 2.x: it's &lt;em&gt;advisable&lt;/em&gt; to upgrade to this version.&lt;/p&gt;

&lt;p&gt;Python 3.x: it's &lt;strong&gt;highly recommended&lt;/strong&gt; to upgrade to this version, as it resolves some core
issues that went under the radar in 3.2.0.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Toying with Context Managers</title>
   <link href="http://tomerfiliba.com/blog/Toying-with-Context-Managers"/>
   <updated>2012-02-27T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Toying-with-Context-Managers</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://verydemotivational.files.wordpress.com/2010/12/demotivational-posters-context.jpg&quot;&gt;
&lt;img src=&quot;http://verydemotivational.files.wordpress.com/2010/12/demotivational-posters-context.jpg&quot; title=&quot;Very Demotivational&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I promised in the &lt;a href=&quot;http://tomerfiliba.com/blog/Code-Generation-Context-Managers&quot;&gt;code-generation using context managers post&lt;/a&gt;,
I wanted to review some more, rather surprising, examples where context managers prove handy.
So we all know we can use context managers for resource life-time management: before entering the
&lt;code&gt;with&lt;/code&gt;-suite we allocate (open) the resource, and when we leave the suite, we free (close) it --
but there's much more to context managers than meets the eye.&lt;/p&gt;

&lt;h3&gt;Stacks, for Fun and Profit&lt;/h3&gt;

&lt;p&gt;We've seen this one in the code-generation post, but we can generalize this notion a bit. Every time
we enter a &lt;code&gt;with&lt;/code&gt; block, we'd append an element to a list, which we'd pop on exit. Consider this
snippet:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Stacking&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@contextmanager&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Nothing fancy, but that's exactly how the code generation framework works: whenever you enter a new
block, it's pushed onto the &quot;stack&quot;, and whenever we leave the block, the top-of-stack element is
popped. This is how we automatically take care of indentation, curly-braces, etc.&lt;/p&gt;

&lt;p&gt;But of course this pattern is much more useful. Consider something like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_envstack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@contextmanager&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_envstack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_envstack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_envstack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_envstack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/tmp/foo/bin&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SHELL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;zsh&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# processes created here will use the modified environment&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We can also leverage this concept to run commands as different users. Here's a sketch:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;ls&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;                       &lt;span class=&quot;c&quot;&gt;# as current user&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;root&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;ls&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/proc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;c&quot;&gt;# as `root`&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;mallory&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;rm&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;-rf&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# as `mallory`&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;cat&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/etc/passwd&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# back as `root` again&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In essence, every time you want to make local/undoable changes to your state, this pattern proves
helpful.&lt;/p&gt;

&lt;h3&gt;Contextbacks&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Contextbacks&lt;/em&gt;, a pun on &lt;em&gt;callbacks&lt;/em&gt;, are contexts you pass as arguments to other functions. Many
times it's useful to pass a before-function and an after-function, and contextbacks are a nice
way to encapsulate this. So instead of this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;beforefunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;afterfunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;beforefunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# your code goes here&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;afterfunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You get this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctxback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctxback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# you code goes here&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Not a ground-breaking change, but I prefer it as it's more concise.&lt;/p&gt;

&lt;h3&gt;Lightweight Asynchronism&lt;/h3&gt;

&lt;p&gt;This is probably my favorite use case for contexts: you can use them to &lt;em&gt;pipeline&lt;/em&gt; or &lt;em&gt;interleave&lt;/em&gt;
long-lasting tasks. You can think of contexts are degenerate forms of &lt;a href=&quot;http://en.wikipedia.org/wiki/Coroutine&quot;&gt;coroutines&lt;/a&gt;,
in which you have defined beginning and end, but the middle part is interchangeable, so you can
stick anything into it.&lt;/p&gt;

&lt;p&gt;Imagine you need to format a harddisk (using &lt;code&gt;mkfs&lt;/code&gt;) or perform some long network operation (like
copying a huge file over &lt;code&gt;scp&lt;/code&gt;). The pattern is as follows: initiate the operation, wait for it
to finish, and either return or raise an exception. This fits perfectly well with the way contexts
work -- with one change -- &lt;code&gt;yield&lt;/code&gt; instead of waiting.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@contextmanager&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;format_disk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;devfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;proc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Popen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/sbin/mkfs&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;-t&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;ext3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;devfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;communicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;returncode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FormattingFailed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format_disk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/dev/sda1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format_disk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/dev/sdb1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This saves you time: instead of waiting for the first operation to finish before starting with the
second, you can run them in parallel. The total time would be that of the longest task (not taking
into account the IO bottleneck). You can throw a &lt;code&gt;yield&lt;/code&gt; into any piece of code instead of just
blocking, and use it as a pipelined contextmanager. You can copy three files in parallel, without
resorting to threads or a reactor in the background.&lt;/p&gt;

&lt;p&gt;Of course you could improve that by returning an object that reports the progress of the
operation, e.g.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format_disk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/dev/sda1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format_disk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/dev/sdb1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; is being formatted, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d%%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; completed&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;devfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;d1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_progress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; is being formatted, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d%%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; completed&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;devfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;d2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_progress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And voila! You have a thread-less, light-weight asynchronous framework at hand... a bit like
using a reactor, but without rewriting your code.&lt;/p&gt;

&lt;p&gt;And last, if you can't tweak the blocking parts of the code (e.g., third party libraries), you can
use the &quot;defer to thread&quot; or &quot;defer to process&quot; approach, a la &lt;a href=&quot;http://twistedmatrix.com/trac/&quot;&gt;twisted&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@contextmanager&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;defer_to_thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;thd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# it would be smarter to use a &lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;thd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;                  &lt;span class=&quot;c&quot;&gt;# thread-pool&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thd&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;thd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defer_to_thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defer_to_thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defer_to_thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# do something else in the meanwhile&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So that's all I had in mind. If you have other unorthodox use cases for contexts, I'd love to
hear about them!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Wizard Dialog Toolkit</title>
   <link href="http://tomerfiliba.com/blog/Dialog-Toolkit"/>
   <updated>2012-02-11T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Dialog-Toolkit</id>
   <content type="html">&lt;p&gt;Following my &lt;a href=&quot;http://tomerfiliba.com/blog/Deducible-UI&quot;&gt;Deducible UI post&lt;/a&gt;, and following some of the
criticism it had received, I'd like to share something I've been working on (read: &lt;em&gt;experimenting with&lt;/em&gt;)
at my work place. You see, we have some &quot;interactive wizards&quot; that storage admins use to connect
storage arrays to their hosts (say, a DB server). These wizards prompt you with questions like your
what's your username, the name of the pool/volume, whether it's an iSCSI or a Fiber Channel
connection, etc., and then they go and perform what you've asked for.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-02-11-gandalf.jpg&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These wizards operate in a terminal environment, but we've had thoughts to make GUI/web versions
of them. This would be a considerable effort with the current design. Another issue they currently
have is the mixing of &quot;business logic&quot; and presentation together. For instance, the code that scans the
devices attached to your host also prints ANSI-colored messages or reports its progress. All in
all it works fine, but there's lots of room for improvement.&lt;/p&gt;

&lt;p&gt;I began to investigate this corner a month or two ago. The initial observation was that such wizards
have a pretty rigid and repetitive structure, thus we can find some abstraction or a &quot;toolkit&quot; for
&quot;expressing&quot; wizards more compactly. This has also led to the realization that once the business
logic and presentation are separate, there's no reason to limit ourselves to terminal-based interaction:
our wizard-toolkit could do the plumbing and work with terminals, ncurses, GUIs, web-browsers, etc.
The business logic would remain oblivious, and we could have a nice GUI at zero-cost!&lt;/p&gt;

&lt;p&gt;There was also a second issue of &lt;em&gt;styling&lt;/em&gt;, i.e., printing text in color, that I wanted to get r
id of. This part was easy: I thought, why not employ the model of HTML and CSS? Let's separate the
structure (semantics) of the text from its styling. Instead of printing a banner for titles,
we'll display a &lt;code&gt;Title&lt;/code&gt; object, whose exact appearance is determined by a &quot;style sheet&quot; (a class,
of course, not actually a text document).&lt;/p&gt;

&lt;p&gt;For instance, when we're using a color-enabled terminal, the title would be printed in bold and
followed by an empty line; but if our terminal is color-blind, we'll render the text centered and
surrounded by &lt;code&gt;=&lt;/code&gt; marks. Another example is error-handling: instead of printing error message
in red every time, we'll display an &lt;code&gt;Error&lt;/code&gt; object; on a terminal, this would be rendered as
red text, but when running in a GUI, rendering this object would pop up a message box.
I'm going to ignore this for the rest of this post, as this is really a side issue.&lt;/p&gt;

&lt;p&gt;Now let's get to expressing wizards, or more generally, &lt;em&gt;dialogs&lt;/em&gt;. Following some earlier iterations,
I came to the model where a dialog is a &quot;container object&quot; that's made of &lt;em&gt;dialog elements&lt;/em&gt;. These
elements can be output-only (such as a welcome message), or input-output (such as a message
telling you to choose one of the available options). A dialog is &quot;executed&quot; by a &lt;code&gt;DialogRunner&lt;/code&gt; that
renders it and returns the results gotten from the user. It's quite important to note that dialog
elements within a single dialog cannot be interdependent -- that is, if you want to ask the user
for his name and then show &lt;code&gt;&quot;Hi there %s&quot;&lt;/code&gt; with the user's name, this has to be done as two,
serial dialogs.&lt;/p&gt;

&lt;p&gt;That was quite a lot of babble -- let's see this in action:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WizardApp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iscsi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;iSCSI&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;FC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;un&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Username&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;pw&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Password&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;conf&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;What do you want to configure?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iscsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;conf&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config_fc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config_iscsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;--gtk&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GtkDialogRunner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;My App&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MyApp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TerminalDialogRunner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ANSIRenderer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It's a short and incomplete snippet of course, as I'm only going to cover the big picture. The
&lt;code&gt;main&lt;/code&gt; function creates a dialog object &lt;code&gt;d&lt;/code&gt; and passes it to &lt;code&gt;ui.run&lt;/code&gt;, which &quot;runs&quot; the dialog
and returns the results, as a dictionary. Notice that the dialog elements &lt;code&gt;Input&lt;/code&gt;, &lt;code&gt;Password&lt;/code&gt;
and &lt;code&gt;Choice&lt;/code&gt; all take a first parameter -- this is the key under which the result would be placed
in the returned dictionary, e.g., &lt;code&gt;res[&quot;un&quot;]&lt;/code&gt; would hold the user-provided user name, and
&lt;code&gt;res[&quot;pw&quot;]&lt;/code&gt; would hold the password. &lt;code&gt;Text&lt;/code&gt;, on the other hand, is an output-only element,
so it doesn't return anything and doesn't take a key. Long story short, we're asking the user
to enter some information and choose one of two options, and then continue processing based on the
selected option. At the bottom, we determine how to run the application based on a command-line
switch: if &lt;code&gt;--gtk&lt;/code&gt; is given, we'll run the dialogs through the &lt;code&gt;GtkDialogRunner&lt;/code&gt;; otherwise,
we'll use the &lt;code&gt;TerminalDialogRunner&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And how does it look like? When running on a terminal:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://tomerfiliba.com/static/res/2012-02-11-wizard-terminal.png&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-02-11-wizard-terminal.png&quot; title=&quot;Running in a terminal&quot; width=&quot;100%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And with a single command-line switch, we run as a GTK application:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://tomerfiliba.com/static/res/2012-02-11-wizard-gtk.png&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-02-11-wizard-gtk.png&quot; title=&quot;Running as a GTK application&quot; width=&quot;100%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So of course it's far from perfect, but then again, it's a small research project I've only put
~15 hours into. It suffers from some of the problems I've listed in the deducible UI post, for
instance, the GUI hangs when the business logic performs blocking tasks. This could be solved
by moving to a reactor-based model, but I've tried to keep the existing wizard code in tact as
much as possible. A hanging GUI is not nice, but it's not the end of the world either, and
there are numerous ways to overcome this.&lt;/p&gt;

&lt;p&gt;Another benefit this design brings along is the ability to automate testing by using &lt;em&gt;mock dialog
runners&lt;/em&gt;. Since our business logic is only exposed to the returned dictionary, we can use a
dialog runner that actually displays nothing and returns a scripted scenario each time. We can even
go further: because our business logic &quot;talks&quot; in high-level primitives like &lt;code&gt;Choice&lt;/code&gt;, we can compute
the Cartesian product of all choices and run through each of them. We can show that we've covered
all paths! And we can do this automatically... without people hitting buttons and keeping logs of
their progress.&lt;/p&gt;

&lt;p&gt;Anyway, I just wanted to show that it's feasible. I'm not releasing any code as this project is
currently in very early stages, and it's something I do at work. Perhaps we'll open-source it in
the future, if it proves useful enough.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Just Got Me These</title>
   <link href="http://tomerfiliba.com/blog/Books"/>
   <updated>2012-02-09T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Books</id>
   <content type="html">&lt;p&gt;Hurrah! I just got me these:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0486663523&quot;&gt;&lt;img src=&quot;http://ecx.images-amazon.com/images/I/41aRgMz4h5L._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg&quot; title=&quot;Introduction to Topology&quot; width=&quot;30%&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.amazon.com/gp/product/048646931X&quot;&gt;&lt;img src=&quot;http://ecx.images-amazon.com/images/I/51Czir%2BiJXL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg&quot; title=&quot;Elementary Number Theory&quot; width=&quot;30%&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.amazon.com/gp/product/0486474178&quot;&gt;&lt;img src=&quot;http://ecx.images-amazon.com/images/I/513qqhyP9cL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg&quot; title=&quot;A Book of Abstract Algebra&quot; width=&quot;30%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the CS secretariat refused to let take math courses as electives (thus forcing me into taking
boring stuff like SQL), I think &lt;a href=&quot;http://store.doverpublications.com/by-subject-science-and-mathematics-mathematics.html&quot;&gt;Dover&lt;/a&gt;
books and I are going to become good friends. It's not like I have plenty of time to read them,
but even just seeing them on my bookshelf would make me a happier person :)&lt;/p&gt;

&lt;p&gt;Next on my wish-list are some books on logics and proof theory, category theory, information theory,
and automata and computability. I'll get there some day...&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>WHO HAS CHEEZBURGER?</title>
   <link href="http://tomerfiliba.com/etc/whohas"/>
   <updated>2012-02-03T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/etc/whohas</id>
   <content type="html">&lt;h2&gt;Too much Wireshark...&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://tomerfiliba.com/static/res/2012-02-03-tellcat.jpg&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-02-03-tellcat.jpg&quot; width=&quot;100%&quot; title=&quot;WHO HAS CHEEZBURGER&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Code Generation using Context Managers</title>
   <link href="http://tomerfiliba.com/blog/Code-Generation-Context-Managers"/>
   <updated>2012-01-31T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Code-Generation-Context-Managers</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-01-31-code.jpg&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When I was working on &lt;a href=&quot;http://agnos.sourceforge.net&quot;&gt;Agnos&lt;/a&gt;, a cross-language RPC framework,
I had a lot of code-generation to do in a variety of languages (Python, Java, C#, and C++).
At the early stages, I just appended strings to a list. It was quick and dirty, and it's got the
job done... but that wasn't enough, of course. I've lost the original code already, but it looked
something like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;generate_proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;public class &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Proxy {&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,),&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;    private int uid;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;    public &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Proxy(int uid) {&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,),&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;        this.uid = uid;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&amp;quot;    }&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;    public &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; get&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;() {&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                    &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,))&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;        // ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;    }&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;    public void set&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; value) {&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                            &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;        // ...&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;    }&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typeinfos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;generate_proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ti&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo.java&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There are several problems with this approach. First of all, it's very cumbersome and fragile.
If you forget a comma in the list, two adjacent strings will be concatenated. Also, you have
to do everything yourself, like remembering to close brackets, add semicolons, do the right
indentation, etc. If you wished to split this code into functions, the functions you call would
have to know the indentation level you're calling them at, or the generated code would be
unreadable. This might seem negligible, but think of languages where indentation matters, like
Python...&lt;/p&gt;

&lt;p&gt;The fundamental problem with this approach (and similar ones) is that the &lt;strong&gt;code generator does
not reflect the structure of the generated code&lt;/strong&gt;. The two are diseparate, while it's quite
obvious they should be correlated.&lt;/p&gt;

&lt;p&gt;In order to solve this, I turned to &lt;a href=&quot;http://www.python.org/dev/peps/pep-0343/&quot;&gt;context managers&lt;/a&gt;,
a feature I highly value. Conceptually, context managers provide a way to bind beginning-and-end
into a single entity; this is normally used for resource management -- but we can leverage this
construction further (I'll this review in a different post). Here, I've used them to create
&lt;em&gt;nested blocks&lt;/em&gt;, which allowed me to reflect the structure of the generated code in the code
generator.&lt;/p&gt;

&lt;p&gt;Without going into too many details, I defined a &lt;code&gt;Module&lt;/code&gt; class that exposes a &lt;code&gt;block()&lt;/code&gt;
context manager and a &lt;code&gt;stmt()&lt;/code&gt; function. The module holds a &quot;stack&quot; of blocks, and entering a new
block pushes a it onto the stack. Statements are then appended to the topmost block on the stack.
Now, because this framework is &quot;language-aware&quot;, it can encapsulate language-specific details.
For instance, In Java, a block will be indented correctly and wrapped by brackets; in Python,
we'll append colons to the opening line and indent the block; in C++, if the block begins with
&lt;code&gt;class&lt;/code&gt;, &lt;code&gt;struct&lt;/code&gt; or &lt;code&gt;enum&lt;/code&gt;, we'll append a trailing semicolon as well.&lt;/p&gt;

&lt;p&gt;Here's how it works:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JavaModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;import foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;import bar&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# an empty line&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#...&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;generate_proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;BLOCK&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;STMT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stmt&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;public class {0}Proxy&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;STMT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;private int uid&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;public {0}Proxy(int uid)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;STMT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;this.uid = uid&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;public {0} get{1}()&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;public void set{0}({1} value)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                                            &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ti&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typeinfos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;generate_proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ti&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;render_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo.java&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So what have we gained?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code is much shorter and more concise&lt;/li&gt;
&lt;li&gt;Brackets, semicolons and indentation come out-of-the-box&lt;/li&gt;
&lt;li&gt;We're no longer working with flat lists of strings -- we're working with hierarchal entities
that reflect the structure of the generated code&lt;/li&gt;
&lt;li&gt;And the other way around -- the structure of the generated code is reflected in the generating
code; nested code is indeed nested inside &lt;code&gt;BLOCK&lt;/code&gt;s, thus the &quot;generatee&quot; and generator are
&lt;strong&gt;visually and semantically correlated&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We can easily split our code into functions, as the module maintains an internal stack.
If &lt;code&gt;f()&lt;/code&gt; opened a block and called &lt;code&gt;g()&lt;/code&gt; under it, it the code that &lt;code&gt;g()&lt;/code&gt; generates will be
placed and indented correctly.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I tried to keep my code quite general, so I haven't defined all of the target language's
constructs, but of course we could do that, or at least head in that direction.
It might look like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;generate_proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CLASS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Proxy&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;public&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FIELD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;int&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;uid&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;private&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CTOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;int uid&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# CTOR gets the name of the current class&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;STMT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;this.uid = uid&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;However, there's a question of where we &quot;put our foot down&quot;, or we'll end up writing &lt;em&gt;Java
Combinators for Python&lt;/em&gt;... and then we'll be writing Java in Python. No need for that,
thank you very much.&lt;/p&gt;

&lt;p&gt;The full source code can be found in the
&lt;a href=&quot;https://github.com/tomerfiliba/agnos/blob/master/compiler/src/agnos_compiler/langs/clike.py&quot;&gt;Agnos repository&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Deducible UI</title>
   <link href="http://tomerfiliba.com/blog/Deducible-UI"/>
   <updated>2012-01-27T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Deducible-UI</id>
   <content type="html">&lt;h3&gt;A Brief History&lt;/h3&gt;

&lt;p&gt;I like automating things. I don't like having to reiterate myself: my dream is to always be able
to add only the &lt;strong&gt;necessary amount of information&lt;/strong&gt; in order to make something possible.
This is one reason, for instance, why I hate expressions like
&lt;code&gt;ArrayList&amp;lt;String&amp;gt; x = new ArrayList&amp;lt;String&amp;gt;();&lt;/code&gt;... it always makes me feel like I'm talking to a
retard (compiler).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://ccrma.stanford.edu/~sangwlee/256a/SharePhone/&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-01-27-sketch.jpg&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In 2006/7, I wrote some demos for &lt;a href=&quot;http://rpyc.sf.net&quot;&gt;RPyC&lt;/a&gt; to show how easy network-related
tasks become. I chose something rather complex, a chat client, to show that all the code sums
up to a few lines: clients invoke a method on the server, say &lt;code&gt;broadcast(str)&lt;/code&gt;, and the server
then invokes callbacks on all of its clients, sending them the message.&lt;/p&gt;

&lt;p&gt;In order to make it usable, I had to write a GUI: I chose Tk, because it comes with python
and is quite simple; I knew there were better toolkits, but my GUI was meant to be basic enough
to be doable in any toolkit. It occurred to me, then, that I wrote ~20 lines show-casing RPyC
and ~100 lines of horrible GUI code, and that something must be really wrong here.
And by &lt;em&gt;here&lt;/em&gt; I mean &lt;em&gt;everywhere&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Note: throughout the article, I'm using the word &lt;em&gt;GUI&lt;/em&gt; to mean any &lt;em&gt;interactive user interface&lt;/em&gt;,
be it graphical (Qt, GTK, wxWidgets, ...) or terminal-based (&lt;code&gt;curses&lt;/code&gt; and the like).
Basically, anything that doesn't block on a single line of input, like shells.&lt;/p&gt;&lt;/blockquote&gt;

&lt;h3&gt;GUI Designers&lt;/h3&gt;

&lt;p&gt;So you might say, &quot;Dude, just use QtDesigner or something&quot;. A GUI designer lets you visually
place components and makes your life much easier -- drag and drop your widgets and double-click on
a button to write its action. Very easy indeed. But I would like to offer a different angle on
the subject: just like the invention of &lt;a href=&quot;http://www.youtube.com/watch?v=N0OhXxx7cQg&quot;&gt;the teacup&lt;/a&gt;
has hindered the technological advance of China, so do GUI designers hinder us from developing
better GUIs. These designers offer a local optimum which we fail to surpass, and this leaves us
with the mediocre UIs and development tools we have today. And get me going about XAML.&lt;/p&gt;

&lt;p&gt;Think about it: &lt;strong&gt;you&lt;/strong&gt; have to design a GUI. So yeah, it's kind of simple, but doesn't that break
DRY? You have the code and you have the GUI -- two faces of the same idea. Obviously, one should
be derived from the other.&lt;/p&gt;

&lt;p&gt;For the lion's share of programs, the UI is highly deterministic -- there's some information
that needs to be displayed to- or gotten from the user, and the &lt;em&gt;bindings&lt;/em&gt; is trivial.
Consider a login screen: you want to get a username and a password, use them somehow, and proceed
to the next screen. This is a repeating task, and I'd guess that for ~80% of the programs in the
world, it's easy enough to &lt;strong&gt;automatically deduce&lt;/strong&gt; how the UI should look, given the task at hand.
And I'm not talking about machine learning algorithms or designing &quot;families of tasks&quot; -- way
simpler than that! Just define a mapping between programmatic primitives and their visual
representation.&lt;/p&gt;

&lt;h3&gt;Deducing UI&lt;/h3&gt;

&lt;p&gt;The ultimate goal is to take &quot;pure code&quot;, unaware of UI, and by adding the necessary metadata,
be able to automatically create (&quot;deduce&quot;) a GUI for it. In fact, I'd like to expose programmatic
APIs to a human -- completely interchangable programmatic- and human- interfaces. Think how cool it
could be to import &lt;em&gt;Adobe Photoshop&lt;/em&gt; and run a directory full of pictures through its filters,
instead of doing so through the UI... without Adobe having to write a separate GUI and
programming toolkit.&lt;/p&gt;

&lt;p&gt;The UI needn't be an eye-candy, at least at the beginning; &lt;strong&gt;it just has to be good-enough&lt;/strong&gt;.
It won't work for games or complex applications like Office, but for it would be just fine for a
chat client. Let's assume the following mapping:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An object is represented by a window&lt;/li&gt;
&lt;li&gt;Read-only instance attributes are represented as labels&lt;/li&gt;
&lt;li&gt;Writable instance attributes are represented as textboxes&lt;/li&gt;
&lt;li&gt;Methods are represented by buttons. If a method requires arguments,
it would be preceded by textboxes&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Of course we could change textboxes and labels to reflect the attribute's or argument's type --
&lt;code&gt;DateTime&lt;/code&gt; would be represented by a &lt;code&gt;DatePicker&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt; could be represented by a number box with
up/down arrows, etc. And of course the framework is free to change the mapping however it wants,
to achieve better, more coherent representation. The mapping above is just a rough draft.&lt;/p&gt;

&lt;p&gt;Now, instances of a class like the following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;birthdate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foodstuff&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{...}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;would turn into&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-01-27-render.png&quot; title=&quot;Created using http://ditaa.org/ditaa/&quot;/&gt;&lt;/p&gt;

&lt;!--
    +-----------------------------------------+
    | Person                            |X|^|_|
    +-----------------------------------------+
    | firstName: | John       |               |
    | lastname:  | Smith      |               |
    | birthdate: | 1-APR-1899 |               |
    |                                         |
    | /-------\                               |
    | | dance |                               |
    | \-------/                               |
    |                                         |
    |  ________   /-----\                     |
    | |________|  | eat |                     |
    |             \-----/                     |
    |                                         |
    +-----------------------------------------+
--&gt;


&lt;p&gt;with just a little bit of binding in the form of:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;java&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Main&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(...);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;guify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Straightforward, isn't it? You can already begin to see the benefits. This framework would obviously
require some sort of decoration (annotations in Java, attributes in C#, ...) on which classes and
which class members are to be exposed, and perhaps some extra metadata, like a picture
to show instead of a method's name, or some layout information -- but it's perfectly doable.
And we can turn it better looking (unlike my beautiful ASCII art example), by using better UI
primitives and a better mapping between objects and their representation; but let's leave it for now.&lt;/p&gt;

&lt;p&gt;I wrote a a simple prototype of this and lo and behold, it actually worked! But when you try to
use it in a real-life applications, the going gets tough: things are updated behind the scenes
(not through our UI framework) and we need to reflect these changes in the UI. For instance,
an element is added to a list via the list's &lt;code&gt;add()&lt;/code&gt; method - how can the GUI become aware of that?
Well, we can use &lt;a href=&quot;http://en.wikipedia.org/wiki/Observer_pattern&quot;&gt;observable objects&lt;/a&gt;, which the GUI
would observe; so instead of using an &lt;code&gt;ArrayList&amp;lt;T&amp;gt;&lt;/code&gt;, you'd simply use an &lt;code&gt;ObservableArrayList&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But creating an observable counterpart for every class is a considerable effort on the framework's
side, and it breaks software modularity: the framework has to be aware of every 3rd party class
that you wish to expose, or at least allow you to provide the means to expose them.
Another downside of this scheme is that your code becomes &lt;em&gt;aware&lt;/em&gt; of the GUI: if we've so far
managed to keep our code clean of GUI primitives (we only required some metadata), all of the
sudden you must replace your lists with GUI-observable-lists. Bummer.&lt;/p&gt;

&lt;p&gt;Another issue is that using synchronous programming techniques (blocking operations) does not
play well with this model: when does the GUI gets its &quot;runtime&quot;? How can we keep it from freezing?
Who's providing the entry-point of the program? Does it run in a separate thread?
If so, we risk polluting our code with GUI-related locks (which is countering the whole purpose);
and besides, threads suck and add the incurred complexity is never worth it.
The only feasible option is asynchronous programming (via a reactor) -- but requires that
your code be programmed this way, and it's quite nasty to write such code without proper language
support (e.g., lack of closures, coroutines, etc.).&lt;/p&gt;

&lt;h3&gt;&quot;No Way&quot;&lt;/h3&gt;

&lt;p&gt;As I said, I've been toying with this idea from 2006, and I always get the same response from
colleague programmers: &quot;it would never work&quot;, &quot;it won't be good enough&quot;, &quot;no one would want to
use it&quot;, &quot;users need their eye-candy&quot;, &quot;I need tight control over the layout&quot;, and what not.
Skeptics galore. My answer is always the same: &lt;strong&gt;you never know what your user wants&lt;/strong&gt; -- so who
are you to decide? And besides, you're always to lazy to support proper customization of UI,
so your user must live with your decisions.&lt;/p&gt;

&lt;p&gt;Sure, there are books and dissertations about UX, and you've read them all; but why not just
provide good-enough defaults, and let the rest be customized by the user? Let the framework
deduce a sane layout for your code -- but let's make everything movable/resizable/dockable.
This way, if it makes more sense to place button X to the left of button Y, the user can do
so himself. And let's remember the user's preferences in a file, which we'll load each time
the application runs. And by &quot;user&quot; I'm also talking about your UX expert -- let him/her decide
on a default look (i.e., the preferences file) for the application, which will be shipped with your
product, but the end-user would still be able to move things around. Wouldn't it be easier?
And if you insist, here's the place to stick some machine-learning magic, in order to deduce
better UIs by default.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;So anyhow, I had a working proof-of-concept somewhere, but I think I lost it. It wouldn't be too
hard to recreate it, but at the moment I'm more concerned with &lt;strong&gt;UI combinators&lt;/strong&gt;, which I'll cover
in a future post. Fully deducing a UI is quite a challenge, as a detailed above, but it's doable
nonetheless, and the added-value is huge! I'll get back to it some day, perhaps after I have
better UI combinators... but in the meantime, is there anyone in the audience who's willing to
pick it up?&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Regarding Infix Operators</title>
   <link href="http://tomerfiliba.com/blog/Regarding-Infix-Operators"/>
   <updated>2012-01-25T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Regarding-Infix-Operators</id>
   <content type="html">&lt;p&gt;I got some reactions to the &lt;a href=&quot;http://tomerfiliba.com/blog/Infix-Operators&quot;&gt;Infix Operators&lt;/a&gt; post, and wanted to point
out some things. First of all, I'm not the one who came up with it -- it's a recipe from the
Python Cookbook that's been posted in 2005. I'm not taking credit for it or anything, I just
said I loved the idea and I adapted the code a little.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://2.bp.blogspot.com/-dKF7ujI_yN0/TgWIk8mccWI/AAAAAAAAACI/hONGw2EoW24/s320/Funny+orkut+scraps+funny+dog+pictures+teeths.jpg&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Second, regarding coding style or the &lt;em&gt;pythonicity&lt;/em&gt; of this scheme -- let's be clear, it's a hack.
In order for it to work, the two arguments must refuse to support &lt;code&gt;__or__&lt;/code&gt; on &lt;code&gt;Infix&lt;/code&gt; objects,
which means you can't compose them properly:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Infix&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Infix&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mul&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# this works ok&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mul&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# but this won&amp;#39;t&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;__or__&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;mul() takes exactly 2 arguments (1 given)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It's also magical and unpythonic by nature. You can read in the cookbook comments about a
less-experienced programmer who complained he had to wrap his head around around this. I'd say this
feature is a kin to &lt;em&gt;metaclasses&lt;/em&gt;: they are useful (at times), but there are better, more pythonic
ways to do the same without the magic.&lt;/p&gt;

&lt;p&gt;So why is it useful? First of all, it's an interesting pattern, worth more knowing about
than actually using it. But on the more practical side, it could be very useful in
domain-specific languages (DSL), where it could increase your expressiveness. Consider something
like &lt;a href=&quot;http://construct.wikispaces.com&quot;&gt;Construct&lt;/a&gt;, where you define data structures declaratively:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;ipaddr&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;lenval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;lenval&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;len&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;val&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# interdependencies: &amp;quot;val&amp;quot; is `len` bytes long&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We could replace all sorts of built-in constructs by such &quot;operators&quot;, thus building &quot;data
expressions&quot;. So here's a very early sketch of what it could look it:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# or maybe just&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ipaddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# binding names into the context&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;lenval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UInt8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bind_seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;len&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;len&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Beware: I just made this up, there's no solid concept behind it.&lt;/p&gt;

&lt;h2&gt;See Also&lt;/h2&gt;

&lt;p&gt;If you liked the infix operators idea, have a look at &lt;a href=&quot;https://github.com/JulienPalard/Pipe&quot;&gt;https://github.com/JulienPalard/Pipe&lt;/a&gt;,
which allows for easy functional composition in python.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>All Systems are Go</title>
   <link href="http://tomerfiliba.com/blog/All-Systems-Go"/>
   <updated>2012-01-23T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/All-Systems-Go</id>
   <content type="html">&lt;p&gt;At last, I finished migrating the old &lt;code&gt;drupal&lt;/code&gt; site to github pages. Everything is now fully
revisioned and statically-generated (using Disqus for comments). Jekyll is so cool! I wrote all
the HTML and forged the stylesheets myself... hope you like it.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://cheezburger.com/View/2825781504'&gt;
&lt;img src='http://images.cheezburger.com/completestore/2009/11/10/129023584835271858.jpg' class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyhow, I'm happy with the design now, and I'll start blogging more regularly. I still have
plenty of pages to complete (projects, about-page, etc.), and a few partially-written blogs
posts to polish up, but other generally speaking, we're up.&lt;/p&gt;

&lt;p&gt;If you have any feedback about the design/site, please let me know in the comments below or
via email. Thanks!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Foxx0rz</title>
   <link href="http://tomerfiliba.com/etc/foxx0rz"/>
   <updated>2012-01-22T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/etc/foxx0rz</id>
   <content type="html">&lt;p&gt;This is &lt;strong&gt;Foxx0rz&lt;/strong&gt;, our course' mascot. He's written in &lt;code&gt;C&lt;/code&gt; (compiles under &lt;code&gt;MSVC++ 6&lt;/code&gt; to be exact),
and we had it printed on T-shirts... 'twas fun.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://tomerfiliba.com/static/res/2012-01-22-bigfox.png&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-01-22-bigfox.png&quot; width=&quot;100%&quot; title=&quot;Foxx0rz source code&quot;/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a &lt;a href=&quot;http://tomerfiliba.com/static/res/2012-01-22-foxsrc.c&quot;&gt;downloadable version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this is the output:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://tomerfiliba.com/static/res/2012-01-22-foxrun.png&quot;&gt;
&lt;img src=&quot;http://tomerfiliba.com/static/res/2012-01-22-foxrun.png&quot; width=&quot;100%&quot; title=&quot;Foxx0rz output&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Infix Operators in Python</title>
   <link href="http://tomerfiliba.com/blog/Infix-Operators"/>
   <updated>2012-01-22T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/blog/Infix-Operators</id>
   <content type="html">&lt;p&gt;As you may already know, there are 3 kinds of operators calling-notations: &lt;strong&gt;prefix&lt;/strong&gt; (&lt;code&gt;+ 3 5&lt;/code&gt;),
&lt;strong&gt;infix&lt;/strong&gt; (&lt;code&gt;3 + 5&lt;/code&gt;), and &lt;strong&gt;postfix&lt;/strong&gt; (&lt;code&gt;3 5 +&lt;/code&gt;). Prefix (as well as postfix) operators are used
in languages like LISP/Scheme, and have the nice property of not requiring parenthesis —
there’s only one way to read an expression like &lt;code&gt;3 5 + 2 *&lt;/code&gt;, unlike &lt;code&gt;3 + 5 * 2&lt;/code&gt;.
On the other hand, it reduces code readability and the locality of operators and their arguments.
This is why we all love infix operators.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://imgs.xkcd.com/comics/rps.png&quot; title=&quot;Thanks go to Oren Held; and XKCD, of course&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now imagine I have a function, &lt;code&gt;add(x,y)&lt;/code&gt;, and I have an expression like &lt;code&gt;add(add(add(5,6),7),8)&lt;/code&gt;...
wouldn’t it be cool if I could use infix notation here? Sadly though, Python won’t allow you to
define new operators or change how functions take their arguments... but that doesn’t
mean we have to give up!&lt;/p&gt;

&lt;p&gt;Haskell, for instance, allows you to define custom operators and set their precedence, as well
as invoking &quot;normal&quot; functions as infix operators. Suppose you have a function &lt;code&gt;f(x,y)&lt;/code&gt; — you
can invoke it like &lt;code&gt;f 5 6&lt;/code&gt; or &lt;code&gt;5 `f` 6&lt;/code&gt; (using backticks). This allows us to turn
our previous expression, &lt;code&gt;add(add(add(5,6),7),8)&lt;/code&gt;, into &lt;code&gt;5 `add` 6 `add` 7 `add` 8&lt;/code&gt;,
which is much more readable. But how can we do this in Python?&lt;/p&gt;

&lt;p&gt;Well, there’s this &lt;a href=&quot;http://code.activestate.com/recipes/384122-infix-operators/&quot;&gt;Cookbook recipe&lt;/a&gt;
that provides a very nice way to achieving the same functionality in Python (adapted a little by me):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;functools&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;partial&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Infix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__or__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__ror__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Infix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__call__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Using instances of this peculiar class, we can now use a new &quot;syntax&quot; for calling functions as
infix operators:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Infix&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;11&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Surrounding decorated functions with pipes (bitwise ORs) allows them to take their parameters
infix-ly. Using this, we can do all sorts of cool things:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Infix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instanceof&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And even &lt;a href=&quot;http://en.wikipedia.org/wiki/Currying&quot;&gt;curry&lt;/a&gt; functions:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Infix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;functools.partial object at 0xb7733dec&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;12&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Ain’t that cool?&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>לקט ציטוטי מורים</title>
   <link href="http://tomerfiliba.com/etc/leket"/>
   <updated>2011-12-01T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/etc/leket</id>
   <content type="html">&lt;p&gt;לקט ציטוטים שאספתי במהלך התיכון.
&lt;a href=&quot;http://tomerfiliba.com/static/res/2011-12-01-leket.pdf&quot;&gt;לינק ל PDF&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>RPyC Moves to a New Site</title>
   <link href="http://tomerfiliba.com/blog/RPyC-new-site"/>
   <updated>2011-08-29T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/RPyC-new-site</id>
   <content type="html">&lt;p&gt;RPyC is in the process of migrating from &lt;a href=&quot;http://rpyc.wikidot.com&quot;&gt;http://rpyc.wikidot.com&lt;/a&gt; to it's new (and hopefully final)
location at &lt;a href=&quot;http://rpyc.sourceforge.net&quot;&gt;http://rpyc.sourceforge.net&lt;/a&gt;. Wikidot had served us well, and was easy to maintain,
but they started displaying way to many ads and didn't support &lt;code&gt;rsync&lt;/code&gt; or &lt;code&gt;SSH&lt;/code&gt; access,
which meant I couldn't upload the generated API reference automatically.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://rpyc.sourceforge.net/_static/rpyc3-logo-medium.png&quot; title=&quot;RPyC logo&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The new site is written entirely in ReST using &lt;a href=&quot;http://sphinx.pocoo.org/&quot;&gt;sphinx&lt;/a&gt; and large parts
of it are auto-generated from docstrings in the source code. It's all now part of the
&lt;a href=&quot;http://http://github.com/tomerfiliba/rpyc&quot;&gt;git repository&lt;/a&gt;, and I only have to run
&lt;code&gt;make upload&lt;/code&gt; to upload it all up.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Learning Me a Haskell</title>
   <link href="http://tomerfiliba.com/blog/Learning-Haskell"/>
   <updated>2011-08-17T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Learning-Haskell</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Phew!&lt;/em&gt; Finally the semester's over (just submitted my last project), and it's time to clean
up my ever-so-long backlog. Here goes nothing: I'll start by posting something here,
after this long while of neglect.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://learnyouahaskell.com/&quot;&gt;
&lt;img src=&quot;http://nostarch.com/sites/default/files/imagecache/product_full/lyah.png&quot; title=&quot;LYAH&quot; class=&quot;blog-post-image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I'm sure you already know, I'm a long-time Pythonista, and I'm confident enough in calling
myself a &quot;native speaker&quot; of that language. Although python is my expertise, I'd say I'm
fluent in most other prominent programming languages (say, C, C++, Java, C#, VB), and with
adequate knowledge of many more. It may seem like a good set of skills, but I have to admit
this brings one to a point of stagnation. There comes a time where everything just looks the same:
you take a glimpse at a new language/platform/other technology and sigh, &quot;oh well,
on the surface it's different, but underneath it's all the same sh*t&quot;. You come to the
conclusion that people mostly change the looks-and-feel, but nothing radical could never happen.
And then you skip to the next article.&lt;/p&gt;

&lt;p&gt;Then came &lt;a href=&quot;http://www.haskell.org/haskellwiki/Haskell&quot;&gt;Haskell&lt;/a&gt;: a statically-typed, type-inferred,
highly-expressive functional language. I'm not new to functional programming -- I've programmed
in Scheme, and I even wrote an interpreter for a toy functional-language that I made up in order
to investigate nested-scopes and evaluation models -- but heck, &lt;strong&gt;this one's different&lt;/strong&gt;.
A friend of mine nagged me to learn Haskell for quite a time already, but I was deterred by
Haskell's ugly syntax (it's not Python a'right) and I kept pushing it for &quot;when I have time&quot;.
It always seemed too academic to me, too impractical.&lt;/p&gt;

&lt;p&gt;I think what provoked me into seriously learning Haskell is a pattern called
&lt;a href=&quot;http://en.wikipedia.org/wiki/Continuation-passing_style&quot;&gt;continuation passing style&lt;/a&gt; -- I was
just amazed by the extra power, design simplicity, and greater expressiveness that you get with it.
Of course you can implement it in almost any other language, and in fact it was invented in
Scheme (&lt;code&gt;call/cc&lt;/code&gt;), but Haskell, with its purely-mathematical state of mind, just brings
the best out of things. Haskell has also taught me that expressiveness and conciseness are
not virtues to be underestimated: if you can do something in one line instead of four,
you must be generalizing on some deeper concept that you've previously missed.
It's not just looks-and-feel, this time.&lt;/p&gt;

&lt;p&gt;But let's not go astray. I think the most prominent and well-known feature of Haskell is its
excellent type system. I'm sure you've heard of &lt;em&gt;static languages&lt;/em&gt;, like java or C++,
where every expression has a compile-time type; and I'm sure you've heard of
&lt;em&gt;dynamic (duck-typed) languages&lt;/em&gt;, where there are only run-time types and no checks are (or can be)
performed prior to running the code. In the first case, you curse the compiler for limiting what
you can do (even when it makes perfect sense) and for being bluntly stupid, requiring you to repeat
yourself over and over (&lt;code&gt;FooBar x = new FooBar()&lt;/code&gt;). And because most type systems are so weak,
you find yourself escaping to &quot;duck-typing&quot; techniques like &lt;code&gt;void *&lt;/code&gt; or &lt;code&gt;Object&lt;/code&gt;, and relying on
run-time casts. In the latter case, you find yourself trying to cover the infinite space of
type permutations that your functions have to handle, and soon you pray for &lt;em&gt;some&lt;/em&gt; sort of
validation or restrictiveness.&lt;/p&gt;

&lt;p&gt;When you start learning Haskell, you suddenly realize how weak most type systems are, and that
there are (much) better alternatives. It's like you've been suffering from a blurry vision your
whole life, and suddenly you realize you can wear glasses. Has it ever occurred to you that
type systems are equivalent to proof systems
(the &lt;a href=&quot;http://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence&quot;&gt;Curry-Howard isomorphism&lt;/a&gt;)?
And that a compiler basically tries to prove your code? You can think of compilation errors as
finding a counter-example to your claim! &quot;You said F takes an integer, but I see you try to call
it with a String&quot;... so of course this is a trivial example, one that even a C compiler catches,
but you can make more complicated claims. And then you realize that type systems and compilers
(&quot;provers&quot;) do matter -- a smarter compiler that employs a more powerful type system can prove
or disprove more complicated claims! That's a non-trivial conclusion that most programmers missed...
type systems don't have to suck, and they can actually &lt;strong&gt;work for you&lt;/strong&gt;, unlike Java.&lt;/p&gt;

&lt;p&gt;But what do I know, I'm just learning Haskell now, and besides -- this post is but a teaser.
So do yourself a favor and &lt;a href=&quot;http://learnyouahaskell.com/chapters&quot;&gt;Learn You a Haskell&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Hooking Imports for Fun and Profit</title>
   <link href="http://tomerfiliba.com/blog/Hooking-Imports"/>
   <updated>2011-06-17T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Hooking-Imports</id>
   <content type="html">&lt;p&gt;I really love Python... it's so hackable that it just calls for hacking, inspiring your
imagination to find ways to stretch its boundaries. This time I decided to investigate into
&lt;a href=&quot;http://www.python.org/dev/peps/pep-0302/&quot;&gt;import hooks&lt;/a&gt;, to add some missing functionality I
wanted to have.&lt;/p&gt;

&lt;p&gt;As you probably know, Python uses a &lt;em&gt;flat namespace&lt;/em&gt; for packages, that works on a
&quot;first found first served&quot; basis. Packages are simply searched in linear order, as they appear
in &lt;code&gt;sys.path&lt;/code&gt;: if two directories contain a package named &lt;code&gt;foo&lt;/code&gt;, importing &lt;code&gt;foo&lt;/code&gt; will fetch
package in the first directory. This is normally the desired behavior (as it allows you to
override some modules by changing &lt;code&gt;PYTHONPATH&lt;/code&gt;), but it's also quite limiting.&lt;/p&gt;

&lt;p&gt;Consider the &lt;em&gt;nested package namespace&lt;/em&gt; used by Java and various other languages (e.g., Haskell),
where packages are normally &quot;deeply nested&quot;, as in &lt;code&gt;com.sun.foo.bar&lt;/code&gt; or &lt;code&gt;com.ibm.spam.ham&lt;/code&gt;.
In Haskell, for instance, packages are normally placed under their appropriate &quot;categories&quot;,
e.g., &lt;code&gt;Data.Vector&lt;/code&gt; or &lt;code&gt;Control.Monad&lt;/code&gt;. When you write a new data type, you'll probably put
it under &lt;code&gt;Data&lt;/code&gt;, as in &lt;code&gt;Data.Vector.UberVector&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we were to use something like that in Python, if would require us to have a single &lt;code&gt;com/&lt;/code&gt;
directory, under which lots of sub-packages must be placed. This might be possible, but it's
certainly not the &quot;right way&quot;; and besides, it implies that code written by Sun and IBM is
somehow related (after all, they share the &lt;code&gt;__init__.py&lt;/code&gt; file in &lt;code&gt;com/&lt;/code&gt;), which means one may
affect the other (for better or worse :)).&lt;/p&gt;

&lt;p&gt;It would make much more sense to have separately-installed packages, e.g.,
&lt;code&gt;site-packages/com.ibm.spam.ham&lt;/code&gt; and &lt;code&gt;site-packages/com.sun.foo.bar&lt;/code&gt;, where each package is
independent of the other. Sure, they might share a common &lt;code&gt;com&lt;/code&gt; prefix -- but that's all.
This is especially useful in corporate environments, where multiple teams share common packages
(which usually get very unoriginal names, say, &lt;code&gt;common&lt;/code&gt;), and name collisions are very likely.
It's not a joke: at my work-place, we're know reorganizing our code after such problems. Also,
from a marketing point-of-view, it might make more sense for your customers to
&lt;code&gt;import mycompany.foobar&lt;/code&gt; than just &lt;code&gt;import foobar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But most importantly -- it's &lt;em&gt;composable&lt;/em&gt;. Nested packages allow you to &quot;inject&quot; your package
into another namespace. Take &lt;code&gt;twisted&lt;/code&gt; for instance: it's become so large that it had made more
sense to split it up into sub-packages (&lt;code&gt;twisted.conch&lt;/code&gt;, &lt;code&gt;twisted.news&lt;/code&gt;, ...), and allow
end users to choose which of them they wish to install. However, since Python wouldn't let you have
&lt;code&gt;site-packages/twisted&lt;/code&gt; and &lt;code&gt;site-packages/twisted-conch&lt;/code&gt;, they resorted to hacking &lt;code&gt;distutils&lt;/code&gt;
into doing what they want. If nested packages were supported, you would have a core &lt;code&gt;twisted&lt;/code&gt;
package, with separate add-on packages like &lt;code&gt;twisted-conch&lt;/code&gt;. So why not, really?&lt;/p&gt;

&lt;p&gt;Enter &lt;a href=&quot;http://pypi.python.org/pypi/nimp/&quot;&gt;nimp&lt;/a&gt; (&quot;nested imports&quot;). Without going into too many
technical details, &lt;code&gt;nimp&lt;/code&gt; is a &lt;em&gt;meta-import hook&lt;/em&gt; -- it modifies the way &lt;code&gt;import&lt;/code&gt; statements work.
Specifically, it scans &lt;code&gt;sys.path&lt;/code&gt; and &quot;merges&quot; packages that begin with a common prefix into
&quot;logical packages&quot;. For instance, if you have &lt;code&gt;com-ibm-foo&lt;/code&gt; and &lt;code&gt;com-sun-bar&lt;/code&gt; on your &lt;code&gt;sys.path&lt;/code&gt;,
&lt;code&gt;nimp&lt;/code&gt; will create &lt;em&gt;namespace packages&lt;/em&gt; for &lt;code&gt;com&lt;/code&gt;, &lt;code&gt;com.sun&lt;/code&gt; and &lt;code&gt;com.ibm&lt;/code&gt;.
This would allow code like &lt;code&gt;import com.ibm.foo&lt;/code&gt; or &lt;code&gt;from com.sun.bar import vodka&lt;/code&gt; to work
transparently. All you need to do is run &lt;code&gt;import nimp; nimp.install()&lt;/code&gt; (you can also put it
in your &lt;code&gt;site.py&lt;/code&gt;, so it would happen every time you run a Python process), and you're ready to go.&lt;/p&gt;

&lt;p&gt;This was the first time I wrote an import hook, and I really liked how I easy it was to change
the import mechanism. So today I had another idea -- &lt;strong&gt;lazy imports&lt;/strong&gt;. Of course there's
&lt;a href=&quot;http://peak.telecommunity.com/DevCenter/Importing#lazy-imports&quot;&gt;PEAK's lazyModule&lt;/a&gt; and this
&lt;a href=&quot;http://code.activestate.com/recipes/473888-lazy-module-imports/&quot;&gt;quite complicated recipe&lt;/a&gt;,
but I thought, why not combine the two. Writing code like &lt;code&gt;from peak... import lazyModule; foo = lazyModule(&quot;foo&quot;)&lt;/code&gt;
is cumbersome, while the recipe attempts is too make everything lazy.&lt;/p&gt;

&lt;p&gt;Instead, I created a module called &lt;code&gt;__lazy__&lt;/code&gt;, that when imported, installs a meta-import hook.
This import hook handles only modules that begin with &lt;code&gt;__lazy__&lt;/code&gt;, so instead of importing them,
it returns an &quot;on-demand-loaded module&quot; (i.e., when you try to access an its attributes).
Using it is really simple:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;__lazy__&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;telnetlib&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;telnetlib&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;OnDemandModule &amp;#39;telnetlib&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;telnetlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Telnet&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# forces loading&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class telnetlib.Telnet at 0x015B08B8&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;telnetlib&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;module &amp;#39;telnetlib&amp;#39; from &amp;#39;C:\Python27\lib\telnetlib.pyc&amp;#39;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;__lazy__.xml.dom&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;minidom&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minidom&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;OnDemandModule &amp;#39;xml.dom.minidom&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minidom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseString&lt;/span&gt;   &lt;span class=&quot;c&quot;&gt;# forces loading&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;function parseString at 0x01659CF0&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minidom&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;module &amp;#39;xml.dom.minidom&amp;#39; from &amp;#39;C:\Python27\lib\xml\dom\minidom.pyc&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Note, though, that using &lt;code&gt;from __lazy__.x.y import z&lt;/code&gt; forces the loading of &lt;code&gt;x&lt;/code&gt;, since we use the
dot operator on it. The &lt;code&gt;from __lazy__ import foo&lt;/code&gt; is &quot;truly lazy&quot;&lt;/p&gt;

&lt;p&gt;You can get the code of &lt;code&gt;__lazy__&lt;/code&gt; &lt;a href=&quot;https://gist.github.com/1030448&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Property Classes</title>
   <link href="http://tomerfiliba.com/recipes/Property-Classes"/>
   <updated>2011-05-14T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/Property-Classes</id>
   <content type="html">&lt;p&gt;Tired of creating properties the old way? Python 3 brings an improvement in the form of
multi-stage properties, i.e.,&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;nd&quot;&gt;@property&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# getter&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@foo.setter&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# setter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It still feels very awkward. I can't say my solution is pure elegance, but I find it cleaner.&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;types&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;property_class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;getter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;get&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UnboundMethodType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;getter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;im_func&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;set&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UnboundMethodType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;im_func&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Example&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nd&quot;&gt;@property_class&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_age&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;19&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
 <entry>
   <title>Python is Messy</title>
   <link href="http://tomerfiliba.com/blog/Getslice"/>
   <updated>2011-05-07T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/blog/Getslice</id>
   <content type="html">&lt;p&gt;A couple of days ago, Rudiger, a user of &lt;strong&gt;RPyC&lt;/strong&gt; found a rather surprising bug, that in turn
revealed just how gruesome python's inner workings are. Rudiger was working with two machines,
one 32 bit and the other 64 bit, and one machine had a &lt;code&gt;netref&lt;/code&gt; to a remote list. He then tried
to execute something as simple as &lt;code&gt;mylist[1:]&lt;/code&gt;, which to everyone's surprise threw a very
peculiar exception: &lt;code&gt;OverflowError: Python int too large to convert to C long&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At first, it seemed that the exception originated from the server side, but further investigation
showed it actually originated from the client side, propagated to the server side, and then back
to the client side: very weird indeed. I recreated the scenario with two of my  machines,
and popped up &lt;em&gt;wireshark&lt;/em&gt; to see exactly what was going on there. The last packet before the
&quot;resonating&quot; exception seemed to be invoking &lt;code&gt;__getslice__&lt;/code&gt; on the client-side list object,
passing it 1 as the start index and 9223372036854775807 as the stop index. Where the heck is
that number coming from? I added lots of debug prints and what not, but that strange number
kept appearing there, and it was obviously not my code that placed it there.&lt;/p&gt;

&lt;p&gt;A day later, the answer finally stroke me: 9223372036854775807 is actually &lt;code&gt;0x7fffffffffffffff&lt;/code&gt;,
which is &lt;code&gt;sys.maxint&lt;/code&gt; on 64-bit machines. From that point on, the solution was simple, but it had
revealed a nasty implementation-detail of CPython 2.xx. You see, when getting a slice of an object,
two methods come to play. The first, deprecated, method is &lt;code&gt;__getslice__&lt;/code&gt;, which simply takes
two arguments for start and stop. The second, recommended method, is &lt;code&gt;__getitem__&lt;/code&gt; which accepts
a &lt;code&gt;slice&lt;/code&gt; object instead of an integer. Sadly, &lt;code&gt;&amp;lt;type list&amp;gt;&lt;/code&gt; has both, which are reflected on
the &lt;code&gt;netref&lt;/code&gt; proxy, which causes this rather surprising behavior:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__getitem__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;getitem&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__getslice__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;getslice&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;getitem 7&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;getslice (7, 8)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;getslice (7, 2147483647)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;getitem slice(7, None, None)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;As you can see &lt;code&gt;y[7:]&lt;/code&gt; invokes &lt;code&gt;__getslice__&lt;/code&gt; with &lt;code&gt;sys.maxint&lt;/code&gt;, while &lt;code&gt;y[7:None]&lt;/code&gt; (which is
equivalent) invokes &lt;code&gt;__getitem__&lt;/code&gt; with a &lt;code&gt;slice&lt;/code&gt; object... how lame! So when the server (64-bit)
side code attempts to execute &lt;code&gt;mylist[1:]&lt;/code&gt; it invokes &lt;code&gt;__getslice__&lt;/code&gt; on the client (32-bit) side,
passing it the server's &quot;version&quot; of &lt;code&gt;sys.maxint&lt;/code&gt;, which goes into the C implementation and
blows up. Monkeyballs!&lt;/p&gt;

&lt;p&gt;So the simple (and only) solution to this issue is using &lt;code&gt;mylist[1:None]&lt;/code&gt; when working with
different-width platforms... sorry.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>ctypes - Pointer from Address</title>
   <link href="http://tomerfiliba.com/recipes/ctype-pointers"/>
   <updated>2011-04-27T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/ctype-pointers</id>
   <content type="html">&lt;p&gt;There are times you need to construct a &lt;code&gt;ctypes&lt;/code&gt; pointer from an integer address you have,
say the &lt;code&gt;id&lt;/code&gt; of a python object. I scratched my head for quite a while until I found out a how
to do it properly (with some help from the &lt;em&gt;stackoverflow&lt;/em&gt; guys). Here's what I got:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ctypes&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;typ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;POINTER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contents&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h1&gt;Example&lt;/h1&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;go&quot;&gt;# get the ref count of an object (in a very nasty way :)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;c_long(1)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;c_long(3)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Some words of caution:
* I'm relying here on &lt;code&gt;id&lt;/code&gt; returning the address of an object. This is a weak assumption,
  but it holds (and is likely to continue to hold) for CPython.
* There are APIs for what I showed in the example above... use them instead!&lt;/p&gt;

&lt;p&gt;I'm using this code to dig into the vicious
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms684342(v=vs.85%29.aspx&quot;&gt;OVERLAPPED&lt;/a&gt; structure that's held
inside &lt;a href=&quot;http://docs.activestate.com/activepython/2.4/pywin32/PyOVERLAPPED.html&quot;&gt;PyOVERLAPPED&lt;/a&gt;
for really low-level hacking... Anyway, if anyone finds this recipe useful, feel free to use it.&lt;/p&gt;
</content>
 </entry>
 
 
 
 <entry>
   <title>Copy Function Defaults</title>
   <link href="http://tomerfiliba.com/recipes/Copydefaults"/>
   <updated>2007-02-06T00:00:00-08:00</updated>
   <id>http://tomerfiliba.github.com/recipes/Copydefaults</id>
   <content type="html">&lt;p&gt;Default arguments to functions are evaluated when the function is created, and are stored in the
function object. This cause irritating problems when the default values are in fact mutable,
as only single instance exists:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5, 5]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5, 5, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Sometimes it's the desired behavior, but mostly it's a bug. To solve that bug, we use&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But this idiom adds lots of boilerplate code into functions. The following little decorator solves that problem elegantly.&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;copy&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deepcopy&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;copydefaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;defaults&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func_defaults&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;wrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func_defaults&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deepcopy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;defaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrapper&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Example&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@copydefaults&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
 <entry>
   <title>Weak Methods</title>
   <link href="http://tomerfiliba.com/recipes/Weakmethod"/>
   <updated>2006-09-29T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/Weakmethod</id>
   <content type="html">&lt;p&gt;Many times you would pass bound methods to other functions, as callbacks (i.e., to simulate events,
etc.). However, bound methods (the &lt;code&gt;instancemethod&lt;/code&gt; type) hold a strong reference to their owning
instance (&lt;code&gt;im_self&lt;/code&gt;), which means the existence of a bound method is enough to hold the instance
&quot;alive&quot;, even though your code has lost all references to it.&lt;/p&gt;

&lt;p&gt;Sometimes it's the desired behavior -- but not always. This nifty decorator will solve the problem
by returning a &quot;weakly-bound&quot; method, which means the method will not hold the instance alive.
You'll get &lt;code&gt;ReferenceError&lt;/code&gt; if you try to invoke the method, after the instance has died.&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;go&quot;&gt;from weakref import proxy&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;from types import MethodType&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;class weakmethod(object):&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    __slots__ = [&amp;quot;func&amp;quot;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    def __init__(self, func):&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        self.func = func&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    def __get__(self, obj, cls):&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        if obj is not None:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;            obj = proxy(obj)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        return MethodType(self.func, obj, cls)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Example&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nd&quot;&gt;@weakmethod&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;bound method Foo.bar of &amp;lt;weakproxy at 009FA1E0 to Foo at 009FC070&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;__main__.Foo object at 0x009FC070&amp;gt; 1 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And when we delete the instance &lt;code&gt;f&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;bound method Foo.bar of &amp;lt;weakproxy at 009FA1E0 to NoneType at 1E1D99B0&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ReferenceError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;weakly-referenced object no longer exists&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
 <entry>
   <title>Real Mixins</title>
   <link href="http://tomerfiliba.com/recipes/RealMixins"/>
   <updated>2006-09-22T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/RealMixins</id>
   <content type="html">&lt;p&gt;The normal python paradigm for implementing mixins is using multiple inheritance. Mixin classes
take some measures of precaution as of their design (not to interfere with the &lt;em&gt;derivee&lt;/em&gt;'s MRO as
much as possible), but they are essentially just regular classes, being derived from.&lt;/p&gt;

&lt;p&gt;This code here creates &lt;strong&gt;real&lt;/strong&gt; mixed-in classes: it actually merges one class into another
(&lt;code&gt;CPython&lt;/code&gt; specific), taking care of name-mangling, some complications with &lt;code&gt;__slots__&lt;/code&gt;, and
everything else. As a side-effect, you can also use it to mix &lt;strong&gt;modules&lt;/strong&gt; into classes.&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;inspect&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    mixes-in a class (or a module) into another class. must be called from within&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    a class definition. `cls` is the class/module to mix-in&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;locals&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f_locals&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;__module__&amp;quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;locals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;TypeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;mixin() must be called from within a class definition&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;# copy the class&amp;#39;s dict aside and perform some tweaking&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__dict__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;__doc__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;__module__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;# __slots__ hell&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;slots&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;__slots__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;slots&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;__slots__&amp;quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;locals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;locals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;__slots__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;__dict__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;slots&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;locals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;__slots__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;c&quot;&gt;# mix the namesapces&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;locals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Example&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SomeMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AnotherMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;g&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AnotherMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;h&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;__class__&amp;#39;, &amp;#39;__delattr__&amp;#39;, &amp;#39;__dict__&amp;#39;, &amp;#39;__doc__&amp;#39;, &amp;#39;__getattribute__&amp;#39;, &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;__hash__&amp;#39;, &amp;#39;__init__&amp;#39;, &amp;#39;__module__&amp;#39;, &amp;#39;__new__&amp;#39;, &amp;#39;__reduce__&amp;#39;, &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;__reduce_ex__&amp;#39;, &amp;#39;__repr__&amp;#39;, &amp;#39;__setattr__&amp;#39;, &amp;#39;__str__&amp;#39;, &amp;#39;__weakref__&amp;#39;, &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;f&amp;#39;, &amp;#39;g&amp;#39;, &amp;#39;h&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;bound method Foo.f of &amp;lt;__main__.Foo object at 0x00A96710&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;bound method Foo.g of &amp;lt;__main__.Foo object at 0x00A96710&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;bound method Foo.h of &amp;lt;__main__.Foo object at 0x00A96710&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;h&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;g&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;22&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
 <entry>
   <title>Hooking dir()</title>
   <link href="http://tomerfiliba.com/recipes/Hooking-Dir"/>
   <updated>2006-09-07T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/Hooking-Dir</id>
   <content type="html">&lt;p&gt;While working with proxy objects I found introspection quite hard, as the mechanism of &lt;code&gt;dir()&lt;/code&gt;
just looks at the object's &lt;code&gt;__dict__&lt;/code&gt; (with some exceptions), and there's no way to customize
this introspection. But do not fear, hacking skillz are near! After reading into the machinery
of &lt;code&gt;dir()&lt;/code&gt;, I found a nifty solution to this problem.&lt;/p&gt;

&lt;p&gt;Note: since python 2.6, &lt;code&gt;__dir__&lt;/code&gt; is a special method that's invoked by &lt;code&gt;dir()&lt;/code&gt;, if it exists,
so there's no reason to use this code. Use only on earlier versions of python.&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;__members__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__dir__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Example&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomDir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;__members__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__dir__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__dir__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;a list of fake attributes&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CustomDir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;__class__&amp;#39;, &amp;#39;__delattr__&amp;#39;, &amp;#39;__dict__&amp;#39;, &amp;#39;__dir__&amp;#39;, &amp;#39;__doc__&amp;#39;, &amp;#39;__getattribute__&amp;#39;, &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;__hash__&amp;#39;, &amp;#39;__init__&amp;#39;, &amp;#39;__members__&amp;#39;, &amp;#39;__module__&amp;#39;, &amp;#39;__new__&amp;#39;, &amp;#39;__reduce__&amp;#39;, &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;__reduce_ex__&amp;#39;, &amp;#39;__repr__&amp;#39;, &amp;#39;__setattr__&amp;#39;, &amp;#39;__str__&amp;#39;, &amp;#39;__weakref__&amp;#39;, &amp;#39;a&amp;#39;, &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;attributes&amp;#39;, &amp;#39;fake&amp;#39;, &amp;#39;list&amp;#39;, &amp;#39;of&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
 <entry>
   <title>Module Mixins a la Ruby</title>
   <link href="http://tomerfiliba.com/recipes/Module-Mixins"/>
   <updated>2006-08-29T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/Module-Mixins</id>
   <content type="html">&lt;p&gt;Multiple inheritance is usually considered bad, and many ways to avoid it have been developed.
The first and most notable is &lt;em&gt;interfaces&lt;/em&gt;, which are basically abstract classes (only declaration,
no implementation). Another solution is mix-in classes, which add functionality (&quot;implementation&quot;)
to the class, but do not affect the inheritance tree.&lt;/p&gt;

&lt;p&gt;Mixins differ from regular classes mostly by their semantics (after all, they are just classes):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They would never derive from any class in the inheritance tree of the defined class&lt;/li&gt;
&lt;li&gt;They would never define an &lt;code&gt;__init__&lt;/code&gt; method&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Also, if class Dog is a subclass of class Animal, then an instance of Dog is an instance of Animal
as well (up-cast). On the other hand, a class that derives from a mixin class isn't considered a
subclass of that mixin class. For more info, see &lt;code&gt;DictMixin&lt;/code&gt; in &lt;code&gt;UserDict.py&lt;/code&gt;, or
this &lt;a href=&quot;http://www.rubycentral.com/book/tut_modules.html#S2&quot;&gt;ruby tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ruby came with a strange idea -- &lt;strong&gt;mixin modules&lt;/strong&gt;. I don't find this whole thing quite useful,
as python (unlike ruby) supports multiple inheritance, but I wanted to show it's possible in
python as well. So here's a two-liner metaclass decorator that does the trick.&lt;/p&gt;

&lt;p&gt;Note: in ruby, adding a function to the module would also add it as a method of the class, but
this is not the case here, as python imposes certain (arbitrary) limitations on that. Never mind.&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;mixin(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;)&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__dict__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;==Example==
This is the code of &lt;code&gt;testmixin.py&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@staticmethod&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;boo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And here's a snapshot demo:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;testmixin&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testmixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;zoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;zoo&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;zoo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# foo is a method from testmixin&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;17&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;boo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# foo is a staticmethod from testmixin&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
 <entry>
   <title>Killable Threads</title>
   <link href="http://tomerfiliba.com/recipes/Thread2"/>
   <updated>2006-08-13T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/Thread2</id>
   <content type="html">&lt;p&gt;The &lt;code&gt;thread2&lt;/code&gt; module is an extension of the standard &lt;code&gt;threading&lt;/code&gt; module, and provides the means
to raise exceptions at the context of the given thread. You can use &lt;code&gt;raise_exc()&lt;/code&gt; to raise an
arbitrary exception, or call &lt;code&gt;terminate()&lt;/code&gt; to raise &lt;code&gt;SystemExit&lt;/code&gt; automatically.&lt;/p&gt;

&lt;p&gt;It uses the unexposed &lt;code&gt;PyThreadState_SetAsyncExc&lt;/code&gt; function (via &lt;code&gt;ctypes&lt;/code&gt;) to raise an exception
in the context of the given thread. Inspired by the code of Antoon Pardon at
&lt;a href=&quot;http://mail.python.org/pipermail/python-list/2005-December/316143.html&quot;&gt;http://mail.python.org/pipermail/python-list/2005-December/316143.html&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Issues&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The exception will be raised only when executing python bytecode. If your thread calls a
native/built-in blocking function, the exception will be raised only when execution returns to
the python code.

&lt;ul&gt;
&lt;li&gt;There is also an issue if the built-in function internally calls &lt;code&gt;PyErr_Clear()&lt;/code&gt;, which would
effectively cancel your pending exception. You can try to raise it again.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Only exception &lt;strong&gt;types&lt;/strong&gt; can be raised safely. Exception instances are likely to cause
unexpected behavior, and are thus restricted.

&lt;ul&gt;
&lt;li&gt;For example: &lt;code&gt;t1.raise_exc(TypeError)&lt;/code&gt; and not &lt;code&gt;t1.raise_exc(TypeError(&quot;blah&quot;))&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;IMHO it's a bug, and I reported it as one. For more info, &lt;a href=&quot;http://mail.python.org/pipermail/python-dev/2006-August/068158.html&quot;&gt;http://mail.python.org/pipermail/python-dev/2006-August/068158.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I asked to expose this function in the built-in &lt;code&gt;thread&lt;/code&gt; module, but since &lt;code&gt;ctypes&lt;/code&gt; has become a
standard library (as of 2.5), and this feature is not likely to be implementation-agnostic,
it may be kept unexposed.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;threading&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;inspect&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ctypes&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_async_raise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exctype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;raises the exception, performs cleanup if needed&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exctype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;TypeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Only types can be raised (not instances)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pythonapi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyThreadState_SetAsyncExc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py_object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exctype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;invalid thread id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# &amp;quot;&amp;quot;&amp;quot;if it returns a number greater than one, you&amp;#39;re in trouble, &lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# and you should call it again with exc=NULL to revert the effect&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ctypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pythonapi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PyThreadState_SetAsyncExc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;SystemError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;PyThreadState_SetAsyncExc failed&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;threading&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_get_my_tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;determines this (self&amp;#39;s) thread id&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isAlive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;threading&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ThreadError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;the thread is not active&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;c&quot;&gt;# do we have it cached?&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;_thread_id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_thread_id&lt;/span&gt;
        
        &lt;span class=&quot;c&quot;&gt;# no, look for it in the _active dict&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tobj&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;threading&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_active&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tobj&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_thread_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;AssertionError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;could not determine the thread&amp;#39;s id&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;raise_exc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exctype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;raises the given exception type in the context of this thread&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_async_raise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_get_my_tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exctype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;terminate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;raises SystemExit in the context of the given thread, which should &lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        cause the thread to exit silently (unless caught)&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;raise_exc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ne&quot;&gt;SystemExit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Example&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;thread2&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;outta here&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isAlive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;terminate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;outta here&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isAlive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
 <entry>
   <title>HTML Codec</title>
   <link href="http://tomerfiliba.com/recipes/HTMLCodec"/>
   <updated>2006-07-26T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/HTMLCodec</id>
   <content type="html">&lt;p&gt;A very simple and straight-forward text/HTML codec. When encoding text, it escapes all
HTML-delimiters (&lt;code&gt;&amp;lt;&lt;/code&gt; becomes &lt;code&gt;&amp;amp;lt;&lt;/code&gt;, etc.), so the encoded text can be safely viewed by an
HTML renderer (browser) or safely embedded into an HTML document. When decoding HTML, it
unescapes the formatters into plain text (so that &lt;code&gt;&amp;amp;gt;&lt;/code&gt; becomes &lt;code&gt;&amp;gt;&lt;/code&gt; again, etc.).&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;amp;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;lt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;br/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;#9;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;nbsp;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;nbsp;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;#9;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;br&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;br/&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;lt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;amp;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Codec APIs (if you place this file in lib/encodings, you can use &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# str.encode(&amp;quot;html&amp;quot;) and str.decode(&amp;quot;html&amp;quot;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;codecs&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HtmlCodec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codecs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Codec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;strict&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;strict&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StreamWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HtmlCodec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codecs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StreamWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HtmlCodec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codecs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getregentry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HtmlCodec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StreamWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Example&lt;/h2&gt;

&lt;p&gt;This module can be used as a standalone module&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;htmlcodec&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;htmlcodec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;blah &amp;gt; yada&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;blah&amp;amp;nbsp;&amp;amp;gt;&amp;amp;bnsp;yada&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Or you can place it in your interpreter's  directory, as  for instance, and then use&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;(blah &amp;gt; yada) &amp;amp; &amp;quot;wow&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;i eat babies&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;html&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;(blah&amp;amp;nbsp;&amp;amp;gt;&amp;amp;nbsp;yada)&amp;amp;nbsp;&amp;amp;amp;&amp;amp;nbsp;&amp;amp;quot;wow&amp;amp;quot;&amp;lt;br/&amp;gt;i&amp;amp;nbsp;eat&amp;amp;nbsp;babies&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;html&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;(blah &amp;gt; yada) &amp;amp; &amp;quot;wow&amp;quot;\ni eat babies&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
 <entry>
   <title>Weak Attributes</title>
   <link href="http://tomerfiliba.com/recipes/Weakattr"/>
   <updated>2006-06-04T00:00:00-07:00</updated>
   <id>http://tomerfiliba.github.com/recipes/Weakattr</id>
   <content type="html">&lt;p&gt;Weak attributes are attributes of an instance that hold only a weak reference to another object.
They are very useful for automatic breaking of cyclic references. This &lt;code&gt;weakattr&lt;/code&gt; class
implements a data-descriptor that holds a weak reference to the attribute, so that when it's no
longer strongly-referenced, it automatically &quot;disappears&quot; from the instance.&lt;/p&gt;

&lt;p&gt;The motivation for this concept comes from &lt;a href=&quot;http://mail.python.org/pipermail/python-3000/2006-June/002357.html&quot;&gt;http://mail.python.org/pipermail/python-3000/2006-June/002357.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Code&lt;/h2&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;weakref&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;weakattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    weakattr - a weakly-referenced attribute. When the attribute is no longer&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    referenced, it &amp;#39;disappears&amp;#39; from the instance. Great for cyclic references.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;__slots__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;dict&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;errmsg&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weakref&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WeakValueDictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errmsg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;r has no attribute named &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%r&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errmsg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%r&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; has no such attribute&amp;quot;&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__repr__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;weakattr at 0x&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%08X&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__get__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;KeyError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errmsg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,))&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__set__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__delete__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;KeyError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errmsg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Example&lt;/h2&gt;

&lt;p&gt;A simple example&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;cyc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weakattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cyc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__del__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;g&amp;#39;bye&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;cyc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# will print False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;__main__.x object at 0x009EEAF0&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cyc&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;__main__.x object at 0x009EEAF0&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cyc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cyc&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;__main__.x object at 0x009EEAF0&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# force a collection&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;g&amp;#39;bye            # printed by y.__del__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False            # printed by y.__del__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0                # return value of gc.collect&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[[code]]&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;In case you wondered what the optional  parameter means&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[[code]]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;attr1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weakattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;attr2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weakattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;attr2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# will not show a name&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attr1&lt;/span&gt; 
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;?&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;24&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;__get__&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;AttributeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;lt;__main__.x object at 0x009EEDD0&amp;gt; has no such attribute&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# will show &amp;#39;attr2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attr2&lt;/span&gt; 
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;?&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;24&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;__get__&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;AttributeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;lt;__main__.x object at 0x009EEDD0&amp;gt; has no attribute named &amp;#39;attr2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And a somewhat more complex one:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;pycon&quot;&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weakattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__del__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;g&amp;#39;bye&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__repr__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;Node &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;node1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;node2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;Node node1&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;Node node2&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;Node node1&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;Node node2&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# forcibly collect the dead objects&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# this will cause node1.next to disappear, so that &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# node2._del__ is be called&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;collect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; 
&lt;span class=&quot;go&quot;&gt;g&amp;#39;bye &amp;lt;Node node2&amp;gt;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</content>
 </entry>
 
 
 
</feed>
