<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Sridatta</title>
 <link href="http://sridattalabs.com/atom.xml" rel="self"/>
 <link href="http://sridattalabs.com/"/>
 <updated>2019-07-18T22:16:45+00:00</updated>
 <id>http://sridattalabs.com/</id>
 <author>
   <name>Sridatta Thatipamala</name>
   <email>sthatipamala@gmail.com</email>
 </author>

 
 <entry>
   <title>Organizing Marc Andreessen's Thoughts Using Python and NLTK</title>
   <link href="http://sridattalabs.com//2014/02/26/pmarca/"/>
   <updated>2014-02-26T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2014/02/26/pmarca</id>
   <content type="html">&lt;p&gt;Marc Andreessen is one of my role models and favorite thought leaders in
entrepreneurship. Back in simpler times, he used to write a &lt;a href=&quot;http://pmarchive.com/&quot;&gt;blog of sagely
startup advice&lt;/a&gt;.  But since joining Twitter, Marc now
shares his thoughts in small bursts of related tweets, forcing me to read his
thoughts in a disjoint, reverse chronological order.&lt;/p&gt;

&lt;p&gt;I decided to use Python fix this terribly pressing problem. The idea is to
create a script that detects tweets posted in quick succession and batches them
together. For amusement, it will also run some rudimentary NLP to generate a
“title” for each batch of tweets. In the end, they will be output as a blog-like
Markdown file (Marc-down file?)&lt;/p&gt;

&lt;h2 id=&quot;the-twitter-api&quot;&gt;The Twitter API&lt;/h2&gt;

&lt;p&gt;First we use &lt;code class=&quot;highlighter-rouge&quot;&gt;twitter&lt;/code&gt; module to OAuth authenticate with Twitter. Despite the
un-Pythonic method names, this module is quite pleasant to use.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;twitter&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;json&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;api&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;twitter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;access_token_key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;REDACTED&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;access_token_secret&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;REDACTED&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;consumer_key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'REDACTED'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;consumer_secret&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'REDACTED'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The Twitter API doesn’t actually provide a way to retrieve every tweet a user
has created. Instead, we have to manually iterate over batches of tweets in
reverse chronological order. Even then, the API limits requests to only the 3200
most recent statuses. While not ideal, it should be good enough for a quick
demo.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_all_user_tweets&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;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tweets&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;offset&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;n&quot;&gt;max_id&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;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;n&quot;&gt;this_batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetUserTimeline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;screen_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_id&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;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exclude_replies&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&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;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;this_batch&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;k&quot;&gt;break&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;offset&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;n&quot;&gt;max_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tweet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tweet&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this_batch&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;tweet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AsDict&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;tweet&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_all_user_tweets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pmarca&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;batching-the-tweets&quot;&gt;Batching the tweets&lt;/h2&gt;

&lt;p&gt;When Marc goes on a Twitter rant, he typically posts several tweets about the
same topic, within minutes of each other. After retreiving all his  statuses,
the next job is therefore to detect batches of tweets posted in quick
succession.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dateutil.parser&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;diff_created_at&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dateutil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&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;&quot;created_at&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;dateutil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&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;s&quot;&gt;&quot;created_at&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;total_seconds&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;batch_tweets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rapidness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;batches&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;curr_batch&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;tweet&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tweets&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;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curr_batch&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;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;diff_created_at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;curr_batch&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;tweet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rapidness&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;curr_batch&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;tweet&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;batches&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;curr_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;curr_batch&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;batches&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;curr_batch&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;batches&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;batch_tweets&lt;/code&gt; function above takes a &lt;code class=&quot;highlighter-rouge&quot;&gt;rapidness&lt;/code&gt; parameter, which is the
maximum time between tweets to them be considered part of the same batch. There
is no science to setting this parameter. Through random observation, I found
that Marc usually posts related tweets within 4 minutes of each other. So we
will use 240 seconds as the value of this parameter.&lt;/p&gt;

&lt;p&gt;Finally, we want to toss out batches of only 1 tweet long because we are only
interested in Marc’s “longform” Twitter content.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;batches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_tweets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tweets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rants&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;batch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batches&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;batch&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;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;/div&gt;
&lt;h2 id=&quot;generating-titles-using-nltk&quot;&gt;Generating titles using NLTK&lt;/h2&gt;

&lt;p&gt;What good are these pseudo blog posts without pseudo titles? Let’s generate some
titles for each batch of tweets using using NLTK. I experimented with various
methods of title generation, from bigram collocation to simply outputting the
most frequent words. They were all pretty crappy.&lt;/p&gt;

&lt;p&gt;The best results came from finding noun phrases in the batches of tweets. While
not perfect, many topics that Marc tweets about are noun phrases, such as
“Entrepreneurial mindset” and “insatiable demand.” Below are some methods to
generate a parse tree out of a sequence of tokens and retrieve the noun phrases.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;nltk&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;nltk.corpus&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stopwords&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;nltk.tokenize&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word_tokenize&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;grammar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NP: {&amp;lt;DT&amp;gt;?&amp;lt;JJ&amp;gt;*&amp;lt;NN&amp;gt;}&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;chunker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nltk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RegexpParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grammar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;stopwords&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stopwords&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'english'&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;leaves&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&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;s&quot;&gt;&quot;&quot;&quot;Finds NP (nounphrase) leaf nodes of a chunk tree.&quot;&quot;&quot;&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;subtree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;leaves&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;subtree&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subtrees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&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;t&lt;/span&gt;&lt;span class=&quot;p&quot;&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;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'NP'&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;extract_terms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;postoks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nltk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pos_tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postoks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;terms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;leaves&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;terms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;outputting-the-marcdown&quot;&gt;Outputting the “Marc”down&lt;/h2&gt;

&lt;p&gt;Finally we put this all together by iterating over the “rants,” generating
pseudo-titles and writing them to a file. If an interesting title couldn’t be
found, it simply outputs “Idea #XYZ”.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&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;&quot;rants.md&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;w&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;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rant_count&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;n&quot;&gt;f&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;&quot;# The Tweets of Marc Andreessen &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&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;rant&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tokens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&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;chain&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;n&quot;&gt;word_tokenize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text&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;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;filtered_tokens&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;t&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokens&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&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;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&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;n&quot;&gt;stopwords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;nps&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;p&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extract_terms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filtered_tokens&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;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&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;mi&quot;&gt;1&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;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nps&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;0&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' '&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;tok&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nps&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;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf8&quot;&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;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;## On &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&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;else&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;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;## Idea &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rant_count&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;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;reversed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rant&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;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text&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;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf8&quot;&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;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&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;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rant_count&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So how did it turn out? &lt;a href=&quot;/rants.html&quot;&gt;Take a look for yourself here&lt;/a&gt;. The
batching turned out to be fairly accurate in grouping together Marc’s tweets
into a series of related thoughts. The autogenerated titles are hit or miss.
Half of them are gibberish and half are surprisingly accurate. Given the
simplicity of the natural language functions I wrote, I’m not surprised.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Enchantments of Elm: Part 1</title>
   <link href="http://sridattalabs.com//2013/12/25/elm/"/>
   <updated>2013-12-25T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2013/12/25/elm</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/CsLg22Z.png&quot; alt=&quot;Some other roguelike&quot; title=&quot;Totally not
Enchantments of Elm&quot; /&gt;&lt;/p&gt;

&lt;p&gt;TL;DR: I’m making a game in a browser based functional language called Elm. Here’s a simple Hello World-type &lt;a href=&quot;/part1.elm.html&quot;&gt;demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Inspired by &lt;a href=&quot;http://prog21.dadgum.com/23.html&quot;&gt;purely functional retro
games&lt;/a&gt;
and Steve Losh’s &lt;a href=&quot;http://stevelosh.com/blog/2012/07/caves-of-clojure-01/&quot;&gt;The Caves of Clojure
series&lt;/a&gt;,
I’ve decided to write a roguelike game in a variant of Haskell called
&lt;a href=&quot;http://elm-lang.org/&quot;&gt;Elm&lt;/a&gt;. I call the game “The Enchantments of Elm”,
keeping with Steve’s alliterative naming.&lt;/p&gt;

&lt;p&gt;According to the language’s website, Elm is a functional language that
compiles to HTML, CSS, and JavaScript. It is designed for functional
reactive programming, which is based on the idea of auto-updating values
(similar to two-way data binding in Angular.js). To me, this seems like
an ideal language to write a browser-based game.&lt;/p&gt;

&lt;p&gt;I plan to develop this roguelike over time and blog about it. 
This series is best if you’re familiar with functional programming
concepts such as high-order functions and combinators.
This first iteration of the game isn’t that exciting. 
It waits for the player to hit Enter and then ends the game.&lt;/p&gt;

&lt;p&gt;Let’s get started. First some necessary imports that we will use later.&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Keyboard&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Window&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;state-manipulation&quot;&gt;State Manipulation&lt;/h2&gt;

&lt;p&gt;Our game will need a state object to store player stats, inventory and
such.
Like in other languages with immutable data structures, the state will
be manipulated by functions that accept the current state and return a
new state.&lt;/p&gt;

&lt;p&gt;For now, we only keep track of whether the game has ended yet. 
Elm has a data structure called a record, which is similar to a
dictionary. We’ll
define a &lt;code class=&quot;highlighter-rouge&quot;&gt;GameState&lt;/code&gt; type to be a record with one field.&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GameState&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;finished&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’ll make a function to return the default state of the game.
Naturally, the &lt;code class=&quot;highlighter-rouge&quot;&gt;finished&lt;/code&gt; property will start out as false.&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;defaultGame&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GameState&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;defaultGame&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;finished&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s time to write that &lt;code class=&quot;highlighter-rouge&quot;&gt;update&lt;/code&gt; function to transform the state.
This function will get called on user input, namely when the player
presses Enter. It ignores the &lt;code class=&quot;highlighter-rouge&quot;&gt;input&lt;/code&gt; for now since it just tells us
that the key has been pressed.&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GameState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GameState&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;finished&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;of&lt;/span&gt;
                       &lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;
                       &lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;finished&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;signals-and-frp&quot;&gt;Signals and FRP&lt;/h2&gt;

&lt;p&gt;Now we get to the fun part of Elm. While game programming in most
languages
would involve a main loop, Elm doesn’t have loops at all. Updates are
triggered
by &lt;code class=&quot;highlighter-rouge&quot;&gt;Signal&lt;/code&gt;s, which represent “reactive” values.&lt;/p&gt;

&lt;p&gt;The one we care about for now is the built-in signal &lt;code class=&quot;highlighter-rouge&quot;&gt;Keyboard.enter&lt;/code&gt;. 
It gets triggered when the Enter key is pressed.&lt;/p&gt;

&lt;p&gt;Instead of writing handlers or callbacks, we will write a function
called &lt;code class=&quot;highlighter-rouge&quot;&gt;gameState&lt;/code&gt; that “collects” keyboard Signal events and turns them
into game state Signals.&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;gameState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Signal&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GameState&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gameState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foldp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defaultGame&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Keyboard&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;foldp&lt;/code&gt; is a folding function over a Signal (which I think are
applicative functors…) Every time &lt;code class=&quot;highlighter-rouge&quot;&gt;Keyboard.enter&lt;/code&gt; is triggered,
&lt;code class=&quot;highlighter-rouge&quot;&gt;foldp&lt;/code&gt; will call
&lt;code class=&quot;highlighter-rouge&quot;&gt;update&lt;/code&gt;, which turns a signal input and current state into a new state.
In this way, user interactions 
can trigger changes to our game’s state.  We pass &lt;code class=&quot;highlighter-rouge&quot;&gt;defaultGame&lt;/code&gt; as the
starting value.&lt;/p&gt;

&lt;h2 id=&quot;rendering&quot;&gt;Rendering&lt;/h2&gt;

&lt;p&gt;All this state manipulation is useless if it doesn’t output anything to
the screen. So we’ll define a function called &lt;code class=&quot;highlighter-rouge&quot;&gt;renderState&lt;/code&gt; that does
just that. It displays a different message depending on whether or not
the game has finished.&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;renderState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GameState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Element&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;renderState&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;finished&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;kr&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;finished&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;of&lt;/span&gt;
                      &lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plainText&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Press enter to end game&quot;&lt;/span&gt;
                      &lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plainText&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;GOODBYE&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href=&quot;http://docs.elm-lang.org/&quot;&gt;Elm standard library&lt;/a&gt; has many text and
image processing functions. 
As this game becomes a real roguelike, that functionality will be useful
to render menues, map tiles, and character sprites.
For now, we are just going to use the plaintext features.&lt;/p&gt;

&lt;p&gt;Finally our &lt;code class=&quot;highlighter-rouge&quot;&gt;main&lt;/code&gt; function ties everything together. It takes the
rendered &lt;code class=&quot;highlighter-rouge&quot;&gt;gameState&lt;/code&gt; and passes it to &lt;code class=&quot;highlighter-rouge&quot;&gt;display&lt;/code&gt;, which just puts it on
the center of the screen.&lt;/p&gt;

&lt;p&gt;Earlier I said that &lt;code class=&quot;highlighter-rouge&quot;&gt;gameState&lt;/code&gt; is itself a signal. Whenever the
&lt;code class=&quot;highlighter-rouge&quot;&gt;gameState&lt;/code&gt;
signal triggers, &lt;code class=&quot;highlighter-rouge&quot;&gt;main&lt;/code&gt; will re-render and display it.&lt;/p&gt;

&lt;p&gt;Note that we lift &lt;code class=&quot;highlighter-rouge&quot;&gt;renderState&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;display&lt;/code&gt; in order to apply them to
Signals.&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;display&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;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&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;kt&quot;&gt;Element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Element&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;p&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;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;middle&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;el&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lift2&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Window&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dimensions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lift&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;renderState&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gameState&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let us enjoy the fruits of our labor. Click here or enjoy this very
visually impressive screen capture.&lt;/p&gt;

&lt;video autoplay=&quot;autoplay&quot; loop=&quot;&quot;&gt;
  &lt;source src=&quot;/public/video/elm_part1.webm&quot; type=&quot;video/webm; codecs=&amp;quot;vp8, vorbis&amp;quot;&quot; /&gt;
  &lt;source src=&quot;/public/video/elm_part1.mp4&quot; type=&quot;video/mp4; codecs=&amp;quot;avc1.42E01E, mp4a.40.2&amp;quot;&quot; /&gt;
  Video tag not supported. Download the video &lt;a href=&quot;/public/video/elm_part1.webm&quot;&gt;here&lt;/a&gt;.
&lt;/video&gt;

&lt;p&gt;Or visit the &lt;a href=&quot;/part1.elm.html&quot;&gt;live demo&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bits and Bobbles: Catchup Edition</title>
   <link href="http://sridattalabs.com//2013/10/28/bits-and-bobbles/"/>
   <updated>2013-10-28T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2013/10/28/bits-and-bobbles</id>
   <content type="html">&lt;p&gt;“Bits and bobbles” is a (supposedly) weekly, curated list of cool things I’ve seen people making on the Internet.&lt;/p&gt;

&lt;h2 id=&quot;1-web-services-as-functions&quot;&gt;1. &lt;a href=&quot;http://monkey.org/~marius/funsrv.pdf&quot;&gt;Web Services as Functions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A Twitter engineer explains how they they model their asynchronous RPC using futures and combinators. Although written in the form of an academic paper, this contains plenty of interesting discussion on real-world benefits and tradeoffs.&lt;/p&gt;

&lt;h2 id=&quot;2-diy-desktop-ct-scanner&quot;&gt;2. &lt;a href=&quot;http://www.tricorderproject.org/blog/towards-an-inexpensive-open-source-desktop-ct-scanner/&quot;&gt;DIY Desktop CT Scanner&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I love this project because of its beautifully laser-cut design and because it’s fairly dangerous as far as DIY bio hacks go. For safety reasons, the creator turned down the radiation level on the x-ray source, so it takes several days to scan a small object. Still amazing for a project whose bill of materials is around $300.&lt;/p&gt;

&lt;h2 id=&quot;3-javascript-nes-emulation&quot;&gt;3. &lt;a href=&quot;http://blog.alexanderdickson.com/javascript-nes-emulator-part-1&quot;&gt;Javascript NES Emulation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In 2011, Notch (of Minecraft fame) announced 0x10c, a spacefaring game involving an in-game programmable CPU. The open-source community rallied to release 0x10c CPU emulators in every major language. 0x10c was sadly cancelled this year.&lt;/p&gt;

&lt;p&gt;But it seems CPU emulation is in vogue again. This article walks through the architecture of the NES’s Ricoh 2A03 chipset and how to write an emulator in Javascript.&lt;/p&gt;

&lt;h2 id=&quot;4-meatspaces-chat&quot;&gt;4. &lt;a href=&quot;http://chat.meatspac.es&quot;&gt;Meatspaces Chat&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Meatspaces Chat is a public chat room that records and attaches an animated GIF of your face every time you send a message. I’ve idled on the site for a while and found it to be a really fun way to communicate. But can it evade being inundated with phalluses?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bits and Bobbles: 10/7/2013</title>
   <link href="http://sridattalabs.com//2013/10/07/bits-and-bobbles/"/>
   <updated>2013-10-07T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2013/10/07/bits-and-bobbles</id>
   <content type="html">&lt;p&gt;“Bits and bobbles” is a weekly, curated list of cool things I’ve seen people making on the Internet.&lt;/p&gt;

&lt;h2 id=&quot;1-nootropics&quot;&gt;1. &lt;a href=&quot;http://www.gwern.net/Nootropics&quot;&gt;Nootropics&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;People already take caffeine to stay alert. Why stop there?
This guy find out whether off the shelf, mind-altering drugs 
can improve your personality and intelligence.&lt;/p&gt;

&lt;h2 id=&quot;2-puzzlescript&quot;&gt;2. &lt;a href=&quot;http://www.puzzlescript.net/documentation/rules101.html&quot;&gt;Puzzlescript&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Puzzlescript lets you create full-featured 2D games in a 100%
declarative way. This isn’t your grandfather’s logic programming
language.&lt;/p&gt;

&lt;h2 id=&quot;3-acme-text-editor&quot;&gt;3. &lt;a href=&quot;http://research.swtch.com/acme&quot;&gt;Acme Text Editor&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Acme is a text editor where all text is UI and all UI is text. This
means you can write scripts to generate GUIs to help you write scripts.
Invented by Rob Pike, the same guy who created Golang.&lt;/p&gt;

&lt;h2 id=&quot;4-bullet-journal&quot;&gt;4. &lt;a href=&quot;http://tomtunguz.com/how-to-take-exceptional-notes-and-be-productive-with-paper&quot;&gt;Bullet Journal&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One problem with being a hipster is you can’t Ctrl-F in your Moleskine.
The “Bullet Journal” method of notetaking tries to solve this problem
without Post-It notes and color coding.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bits and Bobbles: 9/31/2013</title>
   <link href="http://sridattalabs.com//2013/10/01/bits-and-bobbles/"/>
   <updated>2013-10-01T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2013/10/01/bits-and-bobbles</id>
   <content type="html">&lt;p&gt;“Bits and bobbles” is a weekly, curated list of cool things I’ve seen people making on the Internet.&lt;/p&gt;

&lt;h2 id=&quot;1-foolproof-gardening&quot;&gt;1. &lt;a href=&quot;http://www.kickstarter.com/projects/2083391547/nourishmat-changing-the-way-wethink-about-food&quot;&gt;Foolproof Gardening&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My dream is to have an automated vegetable garden which provides me all the produce I need. Projects like the 
&lt;a href=&quot;http://modernfarmer.com/2013/07/nourishmat/&quot;&gt;Nourishmat&lt;/a&gt; give gardening a better UI.&lt;/p&gt;

&lt;h2 id=&quot;2-spark-and-mesos&quot;&gt;2. Spark and Mesos&lt;/h2&gt;
&lt;p&gt;Spark is a data processing framework that is meant to compete with Hadoop. There are &lt;a href=&quot;https://amplab.cs.berkeley.edu/benchmark/&quot;&gt;benchmarks that claim it is faster than Hadoop&lt;/a&gt;, but what I really love is the &lt;a href=&quot;http://spark.incubator.apache.org/docs/latest/scala-programming-guide.html&quot;&gt;API doesn’t make my eyes bleed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Spark is loosely related to Mesos, a distributed job scheduler. Mesos takes a compute cluster and a list of jobs and schedules them efficiently. It can schedule &lt;a href=&quot;https://github.com/mesosphere/marathon/&quot;&gt;long-running&lt;/a&gt; and &lt;a href=&quot;https://github.com/airbnb/chronos&quot;&gt;periodic&lt;/a&gt; jobs. Nice.&lt;/p&gt;

&lt;h2 id=&quot;3-open-source-bio-equipment&quot;&gt;3. &lt;a href=&quot;http://www.instructables.com/contest/buildmylab&quot;&gt;Open Source Bio Equipment&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Cost of equipment makes biology prohibitively expensive for &lt;a href=&quot;http://www.technologyreview.com/lists/innovators-under-35/2013/visionary/lina-nilsson/&quot;&gt;scientists in the developing world&lt;/a&gt;, or just curious hackers. Hacky yet effective open-source designs could bridge the gap.&lt;/p&gt;

&lt;h2 id=&quot;4-xmonad-for-osx&quot;&gt;4. &lt;a href=&quot;https://github.com/xmonad/osxmonad&quot;&gt;Xmonad for OSX&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Xmonad is the grandaddy of tiling window managers. It finally has been extended to support Mac OS X. I already use &lt;a href=&quot;http://www.irradiatedsoftware.com/sizeup/&quot;&gt;SizeUp&lt;/a&gt; but I’m inclined to give this a try.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Sprezzatura</title>
   <link href="http://sridattalabs.com//2013/02/07/sprezzatura/"/>
   <updated>2013-02-07T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2013/02/07/sprezzatura</id>
   <content type="html">&lt;blockquote&gt;
  &lt;p&gt;“Sometimes magic is just someone spending more time on something than anyone else might reasonably expect” - Teller (of Penn and Teller)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I recently came across an interesting concept called &lt;em&gt;sprezzatura&lt;/em&gt;. It’s an Italian term that means “a certain nonchalance, so as to conceal all art and make whatever one does or says appear to be without effort.”&lt;/p&gt;

&lt;p&gt;In many ways, sprezzatura is the antithesis of modern culture. It’s hard to create mystique when your Twitter is a publically accessible stream of consciousness. It’s hard to build conceal your art in the age of nightly builds and continuous integration, when you are encouraged to build fast and break things.&lt;/p&gt;

&lt;p&gt;But it’s the product that matters in the end, not the process. Every peek behind the scenes deprives your audience of the magic and myth they deserve.&lt;/p&gt;

&lt;p&gt;Maybe its time to reconsider the lost art of showmanship.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Facebook's Sponsored Posts Become Smarter (and Creepier)</title>
   <link href="http://sridattalabs.com//2012/11/28/sponsored-stories/"/>
   <updated>2012-11-28T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/11/28/sponsored-stories</id>
   <content type="html">&lt;p&gt;I logged into Facebook today to find my friend’s 5 days old post on the top of my newsfeed. It wasn’t particularly popular so I was curious to see why it had resurfaced nearly a week later. Turns out it was “Sponsored”. I’ve included the post below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/fb-smart-sponsored.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I headed to the Facebook Help Center to double-check what this meant. I found the following.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;What are sponsored stories?&lt;/p&gt;

  &lt;p&gt;Sponsored stories are messages coming from friends about them engaging with your Page, app or event that a business, organization or individual has paid to highlight so there’s a better chance people see them.&lt;/p&gt;

  &lt;p&gt;– &lt;a href=&quot;https://www.facebook.com/help/499864970040521/&quot;&gt;Facebook Help Center&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So there were two possibilities here. Either my friend had paid to surface this post using the new Promote feature, or someone else had paid Facebook to feature this post. My friend denied spending any money to promote this. This is where the mystery begins.&lt;/p&gt;

&lt;p&gt;Sponsored Stories aren’t new to Facebook. When my friends “like” or share a post on some business’s fan page, it is often featured prominently on my newsfeed. This falls under them “engaging with [a] Page, app or event”, just as the Help Center says. I’ve included an example of this below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/fb-regular-sponsored.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But take a look at my friend’s post again, at the top of this article. He wasn’t engaging with any Page, app or event in the sense one might expect. He shared an Amazon link to a product and casually mentioned the product’s name in his post. According to Facebook’s description, there was no reason to believe this post could be targeted by advertisers.&lt;/p&gt;

&lt;p&gt;Additionally, there is no way to know &lt;em&gt;who&lt;/em&gt; had sponsored this story on his behalf.  It could have been Amazon promoting the link to the product page. Facebook has been detecting/de-duplicating newsfeed links for a while:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/fb-link-dedup.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It could equally have been Microsoft promoting his mention of “Halo 4”. Facebook has already been doing some non-trivial topic detection on post content:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/fb-topic-dedup.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Unlike sponsored “likes” and shares, there is no way to discern who is sponsoring these plain, old Facebook posts or why they were sponsored. The fact that companies can target a user’s arbitrary content is a little creepy.&lt;/p&gt;

&lt;p&gt;Many people might be concerned that companies can “detect” what they are talking about and use their words as advertising. I personally do not mind. But the Help Center description of Sponsored Stories is outdated at best and evasive at worst. And I think people deserve to know who is benefiting from the content they post.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Why You Will Never Have a Jetpack</title>
   <link href="http://sridattalabs.com//2012/10/29/why-you-will-never-have-a-jetpack/"/>
   <updated>2012-10-29T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/10/29/why-you-will-never-have-a-jetpack</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://wellmedicated.com/wp-content/uploads/2008/11/01.jpg&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Taking a look around you, you would believe that humanity is on a steady march of progress that carries on without bound. Today we live at the height of freedom and convenience. Some even claim this is nothing compared to &lt;a href=&quot;http://en.wikipedia.org/wiki/Technological_singularity&quot;&gt;what is in store.&lt;/a&gt; As a society, we feel disappointed in ourselves unless we keep up at least a 7% economic growth rate and &lt;a href=&quot;http://en.wikipedia.org/wiki/Moore's_law&quot;&gt;double our technological power every few years.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you think about, such thoughts indicate hubris and irrational bravado. Humans think they can do anything, but it is not without reason. A species of berry-pickers once at the &lt;a href=&quot;http://en.wikipedia.org/wiki/Toba_catastrophe_theory&quot;&gt;brink of extinction during the last Ice Age&lt;/a&gt;, we now rule the Earth and number nearly 7 billion.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.hyperwrite.com/Articles/images/robot_welding_iran.jpg&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Upon more careful inspection, though, it becomes readily apparent that how useless humans really are. Millions of people are unemployed today because machines can do their jobs faster and cheaper than they can. Doctors who train for nearly a decade in their field are routinely outperformed by statistical databases when it comes to diagnoses. Our skills are overshadowed by those of our creations.&lt;/p&gt;

&lt;p&gt;As a last resort, we try to justify humanity’s role in the world by clinging to the intagible “creativity”. There is some quintessential ability within us, we claim, that is impervious to mechanization. Progress seems to require the human spark of ingenuity. But what has this “ingenuity” begotten?&lt;/p&gt;

&lt;p&gt;We learned to split the atom to product unimaginable amounts of energy. But this energy wasn’t used to propel us into the heavens. It was used to fuel an arms race between despots who sold their people dreams of equality and plutocrats who sold their people dreams of materialism.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://tctechcrunch2011.files.wordpress.com/2011/05/sandvine-bandwidth-chart.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the last 100 years, we have created powerful computers and connected them in the largest communication network in history. But it seems &lt;a href=&quot;http://techcrunch.com/2011/05/17/netflix-largest-internet-traffic/&quot;&gt;30% of this vast infrastructure is being used to transport online movies.&lt;/a&gt; The average American uses the &lt;a href=&quot;http://blog.nielsen.com/nielsenwire/online_mobile/facebook-users-average-7-hrs-a-month-in-january-as-digital-universe-expands/&quot;&gt;Internet more often to stalk their friends on Facebook than for any other activity.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Humanity has spent millenia moving mountains and mastering the laws of the Universe only to reinforce our urges to feel loved, important, powerful, and safe. &lt;a href=&quot;http://en.wikipedia.org/wiki/Uncanny_valley&quot;&gt;Any technology that threatens our understanding of ourselves or our relationships is categorically rejected.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s not to say great leaps of progress will not happen. We’ll cure cancer when some determined soul decides to avenge the death of his daughter. We’ll live in space when a generation of young lovers realize Earth is too crowded for them to settle down. We will achieve great things at the last possible moment for the most selfish of reasons, as we always have throughout our history.&lt;/p&gt;

&lt;p&gt;We indulge our human nature at the expense of the The Important Things and maybe that’s okay. Maybe we should accept the fact that despite being the most intelligent, resourceful, and powerful species to have lived, we are after all merely human.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Proposal To Improve Hacker News</title>
   <link href="http://sridattalabs.com//2012/08/17/a-modest-proposal/"/>
   <updated>2012-08-17T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/08/17/a-modest-proposal</id>
   <content type="html">&lt;p&gt;This morning, HN user sw007 reached out the community to explain why &lt;a href=&quot;http://news.ycombinator.com/item?id=4396747&quot;&gt;he/she hates Hacker News&lt;/a&gt;. sw007 is not the first to notice the vile demeanor of the site but it was his/her post that got me thinking about how to improve the community I love.&lt;/p&gt;

&lt;p&gt;I hope these suggestions might inspire the community leaders to consider how small changes to the site can inspire larger social changes in the HN community. But I don’t mean to second-guess PG, the mods or anyone who might know better than me.&lt;/p&gt;

&lt;p&gt;##What doesn’t matter
I’ve read many threads lamenting the state of Hacker News. Inevitably a few suggestions come up that I don’t think are all that effective.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Complaints of “too much startups, not enough tech” or vice-versa:&lt;/p&gt;

    &lt;p&gt;The modern startup founder is a Renaissance Man (or Woman!). They must know new technologies to give themselves a competitive advantage. They must know how to sell their product. And a good founder is aware of current events and humanistic stories, so they can capitalize on changes in society and also empathize with people outside of the Valley bubble. The variety of content on HN fits this ideal very well.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Algorithmic changes&lt;/p&gt;

    &lt;p&gt;Tuning the ranking algorithm may be helpful but only PG knows how best to tweak it. It would be presumptuous of me to suggest “improvements” to an algorithm I know nothing about. Moreover, the problems HN faces are inherently social problems. I think these are best solved by improving the culture and demeanor of the site rather than introducing mysterious formulas.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead, here is what I think would benefit the community the most:&lt;/p&gt;

&lt;p&gt;##Distinguish veteran users
It would be incredibly shocking to see a vitriolic HN comment coming from community leaders like tptacek or patio11. They have worked for years to bolster their reputation and wouldn’t dare lose that respect by snapping at a lackluster “Show HN” post.&lt;/p&gt;

&lt;p&gt;While not all of us can spend the time to become an HN celebrity, there are many of us who have worked to get a high karma over time. HN should highlight the names of such users in purple, similar to the way it highlights newbies with green.&lt;/p&gt;

&lt;p&gt;There are two reasons for this suggestion. First, it reminds other users to tread carefully before bashing a user with a purple name because he/she probably isn’t a total idiot. Two, it reminds these respected users to comment carefully because they have some kind of reputation on the line.&lt;/p&gt;

&lt;p&gt;##Reward users for browsing “New”&lt;/p&gt;

&lt;p&gt;The average up vote count of a front page post has skyrocketed lately. This means that getting from the “new” page onto the front page is a nigh impossible task. The only way to guarantee any visibility is to time very carefully using HNPickup, be a celebrity like John Gruber or Dustin Curtis,  organize an up vote cabal, or write sensationalist content.&lt;/p&gt;

&lt;p&gt;The last three options actively hurt the community. People are fed up with the empty words of blogger pundits and polemics, and are increasingly suspicious of promotional content from influential startups.&lt;/p&gt;

&lt;p&gt;One solution is to reward users for browsing the “New” page and help surface content. Brave souls who upvote or a downvote posts on the New page should be rewarded with HN karma or some other metric. This turns “New” from a seedy underbelly where anything goes into a frequently trafficked page, reducing need to be a celebrity or cheater to garner up votes.&lt;/p&gt;

&lt;p&gt;##Indulge the addicted
HN could benefit from implementing infinite scroll, so the next page is appended asynchronously to the current one. This may sound frivolous but it is not a UI improvement for its own sake.&lt;/p&gt;

&lt;p&gt;In my experience, being on the HN front page is a gift from the Gods while falling to the second page is effectively a death sentence. The problem is only a small minority of readers bother to click the tiny “More” button on bottom of the page.&lt;/p&gt;

&lt;p&gt;Enabling infinite scroll on HN reduces the friction to explore content beyond the front page. Hopefully this increases readership on those less popular articles and diminishes the burning need to write inflammatory content in order to stay on the front page of the site.&lt;/p&gt;

&lt;p&gt;##A hide button for the hot-heads
Hackers like me are hot-headed. We hate to see people be wrong or idiotic so when an absurd post comes onto the front page, we rush to rip it apart.&lt;/p&gt;

&lt;p&gt;Recently I installed an Chrome extension that allows me to hide HN posts I don’t like. Since then, I’ve simply hidden away anything that causes my blood pressure to increase. I’ve become a lot calmer and happier on the site.&lt;/p&gt;

&lt;p&gt;Not every knows about this extension so it might be a good idea to introduce it to the site itself. It would appease the easily angered.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>I'm A Maker, Dammit</title>
   <link href="http://sridattalabs.com//2012/08/12/im-a-maker-dammit/"/>
   <updated>2012-08-12T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/08/12/im-a-maker-dammit</id>
   <content type="html">&lt;p&gt;The other day I encountered this &lt;a href=&quot;http://joelrunyon.com/two3/russell-kirsch-encounter-lessons&quot;&gt;blog post&lt;/a&gt; in which
an entrepreneur accidentally meets Russell Kirsch, computing pioneer and inventor of the first digital photo.&lt;/p&gt;

&lt;p&gt;Kirsch, at the wise age of 81, informs the author of two principles he follows.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Do things that have never been done before&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Nothing is withheld from us what we have conceived to do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Russell Kirsch’s advice to work with determination and courage seems quaintly romantic. It surprises me that his words seem 
foreign to &lt;em&gt;me&lt;/em&gt;, an entrepreneur living in the Silicon Valley.  If anything, the principle of “Making Great Things” 
should be my personal religion. But as I read these blog posts, I could feel that I was not living that way.&lt;/p&gt;

&lt;p&gt;Day to day, I find myself thinking of users as people I need to monetize. I no longer try to “do things that have never been done.”
I do things to get to achieve the mythical goals of Growth and Traction. I judge my work by a yardstick that measures how rich
I make other people. So if “nothing is withheld from us what we have conceived to do,” why am I spending all my time conceiving 
to do things I don’t even care about?&lt;/p&gt;

&lt;p&gt;These principles are not why I got into startups. So from today, I’ve decided to distance myself from this “Silicon Valley way of thinking”.
Hacker News and Lean Startup be damned.&lt;/p&gt;

&lt;p&gt;I’m a maker, dammit. I’m going to go make great things.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Primitive Approach to User Experience</title>
   <link href="http://sridattalabs.com//2012/04/23/primitives/"/>
   <updated>2012-04-23T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/04/23/primitives</id>
   <content type="html">&lt;blockquote&gt;
  &lt;p&gt;“Perfection is achieved not when there is nothing left to add, but when there is nothing left to take away”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;– Antoine de Saint-Exupery&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Designing an engaging and pleasant user experience is a very fragile art. It takes painstaking work to distill the power of a website or software into something that the everyday user can understand. But products from Twitter to Minecraft have become phenomenal successes by crafting their UX from very simple concepts. I dub these concepts “primitives”.&lt;/p&gt;

&lt;p&gt;##What is a primitive?
A primitive is a fundamental building block from which you can build more complicated things. Your computer screen can display millions of colors but they can all be described as a combination of three “primitive” colors - red, green and blue. All of Western music is built up from the 12 notes of the chromatic scale and the rests between them.&lt;/p&gt;

&lt;p&gt;A user experience is also composed of primitives. Consider Facebook for example; the entire site consists of two things: posts and likes. Everything from timeline to events is just a stream of posts presented in different formats and contexts. Extraneous interactions that could not be represented by these (such as “pokes” and Facebook Gifts) have been removed or fallen out of favor.&lt;/p&gt;

&lt;p&gt;Primitives are the key to designing an experience that your users will fall in love with. Picking the right ones results in a sense of familiarity that keeps competitors from poaching your user base. Specifically, a good UX primitive has two qualities:&lt;/p&gt;

&lt;p&gt;###Minimalism
Minimalist primitives are useful out of the box but allow room for experimentation. They enable “emergent properties,” which are interactions that your users invent without your intervention.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.howtogeek.com/geekers/up/sshot4ced9c7bf213a.jpg&quot; alt=&quot;image&quot; /&gt;
&lt;small&gt;Users invented retweets by simply prepending “RT” before messages&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Twitter has used minimalism and emergent properties to great effect. The concept of retweets and hashtags emerged organically from Twitter’s users, who invented them using just 140 character tweets and the “mention” feature. Only later did they formally become part of the product.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://trello.com&quot;&gt;Trello&lt;/a&gt; allows users to create cards and put them into lists. Because of its simplicity, it is possible to use Trello for task management concepts ranging from a simple to-do list to a &lt;a href=&quot;http://en.wikipedia.org/wiki/Kanban&quot;&gt;“Kanban” system&lt;/a&gt; that Toyota uses to manage its factories.&lt;/p&gt;

&lt;p&gt;It is of course possible to go too far with minimalism. Google Wave had a user experience that was so generalized that no one had any idea how to use it. Instead of encouraging ingenuity, it just resulted in frustration.&lt;/p&gt;

&lt;p&gt;###Composability
In addition to being minimalist, the building blocks of your software’s UX should be composable. Having a set of composable primitives means that basic concepts can be combined in different permutations to express more complex interactions. This means that users can “discover” advanced techniques by building on their previous knowledge, rather than having to read how-to guides.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.photoshopessentials.com/images/type/effects/gel/layer-style-db.jpg&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;This window contains most of the magic of Photoshop&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Composability is most often seen in application that are designed for “creators.” Almost every advanced effect in Photoshop is a clever combination of several filters and layer styles. Every seemingly magical keystroke in Vim is a sentence of the form “verb-preposition-subject”. Composability allows users to &lt;em&gt;do&lt;/em&gt; hundreds of different things without having to &lt;em&gt;remember&lt;/em&gt; hundreds of different things.&lt;/p&gt;

&lt;p&gt;##Stretching the definition of UX
These simple principles apply for any type of software interaction, from designing web sites to devising a new programming language. While I use these principles when designing &lt;a href=&quot;http://flotype.com&quot;&gt;clean and powerful APIs for developers&lt;/a&gt;, the same concepts can be used for all software.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How I Learned to Stop Worrying And Love Newbies</title>
   <link href="http://sridattalabs.com//2012/03/31/how-I-learned-to-stop-worrying/"/>
   <updated>2012-03-31T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/03/31/how-I-learned-to-stop-worrying</id>
   <content type="html">&lt;p&gt;I discovered this &lt;a href=&quot;http://thingist.com/t/item/4372/&quot;&gt;open letter to developers&lt;/a&gt; in an HN comment thread the other day. The author points out an concerning trait of many software developers to be overly critical and hateful towards beginners.&lt;/p&gt;

&lt;p&gt;Almost every accomplished designer I know has disparaged &lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Twitter Bootstrap&lt;/a&gt; and (implicitly) the people who use it. I admit I have the same tendencies. As a backend Web developer, I wince just a tad when someone mentions they’ve abstracted their entire application using something like &lt;a href=&quot;https://parse.com/?IStillLoveYouParse&quot;&gt;Parse&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;##The Tables Turn
It is easy to ascribe this defensiveness to snobbery or “get off my lawn” attitude. But in reality, it is easy to see why the old guard sees newcomers as an affront to their skills. Making a concept accessible necessarily requires replacing nuance and individualism with sweeping generalizations. It hurts when the precepts of your craft are reduced to sound bites, code snippets, and &lt;a href=&quot;http://en.wikipedia.org/wiki/Cargo_cult&quot;&gt;cargo cult practices&lt;/a&gt;. Vitriolic essays comparing the &lt;a href=&quot;http://teddziuba.com/2011/10/node-js-is-cancer.html&quot;&gt;software to terminal illnesses&lt;/a&gt; result.&lt;/p&gt;

&lt;p&gt;But then I had to design a front-end for a side project I was making and I found myself with the daunting task of learning all about design. I could pore over articles about typographic style, proper layout and spacing, and graphic design or I could just drop a single Bootstrap script at the top of my HTML. I, the cynical backend guru, could finally empathize with those I had criticized.&lt;/p&gt;

&lt;p&gt;##Embrace
It was then I realized that these easy-to-use tools are not just a convenience but a &lt;em&gt;necessity&lt;/em&gt; for a novice. Technology has progressed to the point that no single person can reasonably know everything about the full software stack. So much of what we know is encoded in implicit knowledge and oral tradition that a beginner would have to struggle for months before they could even get started. Abstraction is required.&lt;/p&gt;

&lt;p&gt;There will always be people in the world who have no appreciation for your craft. Such people have always existed, even before starter kits and frameworks “dumbed things down.” There is nothing you can do except accept that fact. But for everyone else, the availability of tools provides an entry point for learning more advanced theory.&lt;/p&gt;

&lt;p&gt;##Standing Up For Your Principles
Any developer will agree that abstraction is one of the defining tenets of development. A designer should not be expected to know about databases and concurrency, nor a programmer about proper line heights. To disrespect tools like Bootstrap or Parse is to disrespect that principle.&lt;/p&gt;

&lt;p&gt;Now, before I denounce anything aimed at beginners, I remind myself that before learning things “The Right Way,” it is necessary to learn it in the first place.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Problem With Lazy Evaluation</title>
   <link href="http://sridattalabs.com//2012/02/21/lazy-evaluation/"/>
   <updated>2012-02-21T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/02/21/lazy-evaluation</id>
   <content type="html">&lt;p&gt;Imagine you have a landlord who collects your rent check and deposits it in a very unpredictable way. Sometimes he does it immediately. Sometimes he collects the checks for months before cashing them.&lt;/p&gt;

&lt;p&gt;Initially you feel happy about this system because you get to live in your apartment without the money actually leaving your bank account. But soon you realize that the extra money is just a mirage. You can’t plan how much money you need to have at any given time because your landlord may cash your checks right when you don’t have the balance to back it.&lt;/p&gt;

&lt;p&gt;This is the danger of lazy evaluation.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Rabbit holes: Why being smart hurts your productivity</title>
   <link href="http://sridattalabs.com//2012/02/06/rabbit-holes-being-smart-hurts-prod/"/>
   <updated>2012-02-06T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/02/06/rabbit-holes-being-smart-hurts-prod</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;http://imgs.xkcd.com/comics/nerd_sniping.png&quot; style=&quot;width: 600px;&quot; /&gt;
XKCD’s “Nerd Sniping” is the epitome of rabbit holing&lt;/p&gt;

&lt;p&gt;##The geek’s Achille’s Heel
I recently decided practice my algorithms skills everyday by working through Skiena’s &lt;a href=&quot;http://www.amazon.com/gp/product/1849967202/&quot;&gt;Algorithm Design Manual&lt;/a&gt; and doing some &lt;a href=&quot;http://www.interviewstreet.com/recruit/challenges/&quot;&gt;Interview Street&lt;/a&gt; problems. To make it somewhat more interesting I decided to do all the exercises and problems in Haskell.&lt;/p&gt;

&lt;p&gt;On my second day of practice, I felt the urge to find a better Haskell syntax highlighting extension for Vim. I managed to find one that was distributed in a package called a “Vimball”. I spent 10 minutes trying to figure out how to install a Vimball and then another 10 customizing the plugin’s settings.&lt;/p&gt;

&lt;p&gt;Absolutely none of that helped me with my ultimate goal of learning about algorithms. By the end of the 30 minutes I allotted, I had 9 browser tabs open about useless trivia and I had not advanced a single page in my textbook.&lt;/p&gt;

&lt;p&gt;The names change but the story remains the same. Designers find themselves studying fancy, new CSS3 effects when they should have been wire framing their checkout page. Hapless students find that they are on the Wikipedia page for Esperanto instead of writing notes on Norse mythology. Like Alice led into Wonderland by the White Rabbit, geeks too easily fall into “the rabbit hole”.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://the-office.com/bedtime-story/alice_lg.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The most insidious part of this “rabbit hole” phenomenon is how unaware its victims are. We are lured into thinking we are making progress. What if this new language and setup this new stuff could help program &lt;em&gt;so&lt;/em&gt; much better? How could you do something without having explored every tool and technique at you disposal?&lt;/p&gt;

&lt;p&gt;As geeks, our pursuit of perfection and perfect information distract us from the task at hand, but it turns out that it is not always a bad thing.&lt;/p&gt;

&lt;p&gt;##Your weakness is your strength
Going down a rabbit hole is certainly devastating to productivity on a micro scale. But it is also a valuable “skill” when it comes to solving hard problems. Richard Feynman was fond of saying:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You have to keep a dozen of your favorite problems constantly present in your mind, although by and large they will lay in a dormant state. Every time you hear or read a new trick or a new result, test it against each of your twelve problems to see whether it helps. Every once in a while there will be a hit, and people will say, “How did he do it? He must be a genius!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If one brilliant researcher wasn’t enough, Richard Hamming puts it yet another way in his essay &lt;a href=&quot;http://www.cs.virginia.edu/%7Erobins/YouAndYourResearch.html&quot;&gt;You and Your Research&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I notice that if you have the door to your office closed, you get more work done today and tomorrow, and you are more productive than most. But 10 years later somehow you don’t know quite know what problems are worth working on … He who works with the door open gets all kinds of interruptions, but he also occasionally gets clues as to what the world is and what might be important. … [T]here is a pretty good correlation between those who work with the doors open and those who ultimately do important things, although people who work with doors closed often work harder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What both of them are saying is that producing brilliant work is heavily reliant on serendipity. Putting your nose to the grindstone will certainly get things done, but when you are working on cutting-edge problems with no predetermined path to success you derive inspiration through chance discoveries.&lt;/p&gt;

&lt;p&gt;Both these men were probably relied on conversations with their brilliant colleagues to deliver them random insights. But they also had the advantage of working at the top of their games at Caltech [1] and Bell Labs, respectively. The common geek today relies on the Internet, especially community watering holes like HackerNews and Reddit, to keep abreast of “what the world is and what might be important”.&lt;/p&gt;

&lt;p&gt;##The solution
We have concluded that random walks of knowledge-gathering keep us from getting things done day-to-day but can also be catalysts for amazing work. Falling down the rabbit hole seems to be an activity best done in moderation. How can you use it to your advantage without letting it damage you?&lt;/p&gt;

&lt;p&gt;My solution is pretty low tech and simple. During my workday, I keep a text editor open on my desktop. In very large text, I write very specifically what I am supposed to be doing at that moment.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/quotes_todo.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Every time I detect that I am wandering, I check back to the window and ask myself whether what I am doing right now will immediately benefit that tasks.&lt;/p&gt;

&lt;p&gt;But then I don’t close the tab or stop my tinkering immediately. Obviously it was fascinating enough that I started looking into it. So I make sure that I record it somewhere so I can go back to it at my leisure.&lt;/p&gt;

&lt;p&gt;For long form text, I am a fan on &lt;a href=&quot;http://www.instapaper.com/&quot;&gt;Instapaper&lt;/a&gt; and I’ve heard great things about &lt;a href=&quot;http://pinboard.in/&quot;&gt;Pinboard.in&lt;/a&gt;. If it wasn’t something on the Internet but something more abstract, like a new feature I discovered in a program, I make a note of it in my Trello board, in a list called “Wishlist”.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/images/trello_wishlist.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Make some time to revisit these repositories of information. It is easy to just hoard web snippets and never use them to your advantage. So set aside some time everyday to update yourself on your findings. It does not have to be much; just 15 minutes will suffice.&lt;/p&gt;

&lt;p&gt;With enough discipline and practice, you may find that you are more productive than ever and maybe people will even say “How did he do it? He must be a genius!”.&lt;/p&gt;

&lt;p&gt;Errata:
Feynman had a career at Caltech, not MIT. Thanks to &lt;a href=&quot;http://news.ycombinator.com/user?id=mturmon&quot;&gt;mturmon&lt;/a&gt; for the
correction.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>HTML5 Has Failed Us</title>
   <link href="http://sridattalabs.com//2012/02/02/html5-has-failed-us/"/>
   <updated>2012-02-02T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/02/02/html5-has-failed-us</id>
   <content type="html">&lt;p&gt;Unless you’ve been living under a rock, you’ve probably heard the fanfare about HTML5 and all it eye-catching splendor. What you don’t know is that HTML5 completely dropped the ball on ensuring that the web will stay free and open.&lt;/p&gt;

&lt;p&gt;##”Shut up, you stupid hippy”
That’s the first thing I think whenever I hear someone preach about the “free and open Internet.” Such rants are heard too often from neckbeards who incessantly rally against sites like Facebook or Twitter (probably because no one wants to friend them).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i1.kym-cdn.com/entries/icons/original/000/003/445/untitled.jpeg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I am not one of those people. Instead, my story starts when I was selecting blogging engines. This blog is implemented in Jekyll but it was almost a Tumblr blog. My greatest regret with rolling my own site is I miss out on the wonderful community that comes with a site like Tumblr. No comments, no one to repost my blog posts on their own pages. This is the price I pay to keep my data open.&lt;/p&gt;

&lt;p&gt;##One little icon that will kill the web&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://4.bp.blogspot.com/-HzztD74ib-w/TrQ0957-IdI/AAAAAAAAAvk/d00Uk1SLd5M/s320/retweet-icon.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That little sharing icon has become the very future of the World Wide Web. Sharing has become the &lt;em&gt;primary&lt;/em&gt; way to consume content on the Internet. Knowledge no longer propagates through hyperlinks; it comes by way of Tumblr reblogs, Twitter retweets, and Pinterest repins. Re, re, re.&lt;/p&gt;

&lt;p&gt;The truth is that HTML does not support any way to share content in this manner. True, images can be remotely referenced by way of hot linking. But what about snippets of text (such as a Tumblr post you want to reblog)? How about a Github commit/issue you want to display inline?&lt;/p&gt;

&lt;p&gt;There simply is not way to tell a browser or – more importantly– a web crawler, that the thing you are seeing here is really just a “view” of some resource somewhere else.&lt;/p&gt;

&lt;p&gt;To anyone who have programmed in Rails or iOS, the concept of separating a view and the underlying model is part of your toolkit. This is sadly impossible with even the latest HTML spec.&lt;/p&gt;

&lt;p&gt;##I like freedom. I like convenience better.
I’m turning the tables on Ben Franklin this time. We’ve demanded social Web standards for over half a decade. What did we get? An incomprehensible alphabet soup like RDF, OWL and SPARQL.&lt;/p&gt;

&lt;p&gt;More than video element and the death of Flash, a better social experience is what HTML5 should have offered us. The HTML standards committee missed the boat on provided an easy and standardized way to relate the shareable snippets that our modern Web is composed of. Instead of being encoded in Hypertext, the underlying relational graph of the web is contained within the databases of private Internet giants.&lt;/p&gt;

&lt;p&gt;I’m not going to stop using the Web because of this. Life is far too short to be an ideologue. But I can’t help but lament what could have been.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Essence of a Good Software Framework</title>
   <link href="http://sridattalabs.com//2012/01/28/the-essence-of-a-good-software-framework/"/>
   <updated>2012-01-28T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/2012/01/28/the-essence-of-a-good-software-framework</id>
   <content type="html">&lt;p&gt;I was reading a &lt;a href=&quot;http://www.decipherinc.com/n/blog/development-and-engineering-team/2011/04/backbone-api-and-events-models&quot;&gt;review of Backbone.js&lt;/a&gt; when I came across a quote that anyone who is writing a software library or programming framework should keep in mind.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I look at Backbone, and I say to myself, “Oh, this is code I’ve written, or wish I’d written only better reviewed and field-tested than the last ad-hoc implementation of this I came up with.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s it. You don’t need a boatload of features and configurability. A framework should abstract a task just enough that it’s better than rolling your own version of it.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Nappy Boy and Pretty Boy: Finding Your Perfect Cofounder</title>
   <link href="http://sridattalabs.com//nappy-boy-and-pretty-boy-finding-your-perfect"/>
   <updated>2012-01-17T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/nappy-boy-and-pretty-boy-finding-your-perfect</id>
   <content type="html">&lt;img src=&quot;/public/tpain.jpg&quot; /&gt;
&lt;p&gt;&lt;em&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Chris Brown (Pretty Boy) and T-Pain (Nappy Boy) consistently produce radio hits together&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;One of the most common problems I hear from friends looking to get into startups is the difficulty in finding a cofounder. While I was fortunate enough to stumble upon my own cofounders, I can empathize.&amp;nbsp;It seems that the interests of business people are at odds with those of engineers. It's easy for one party to feel shortchanged or for visions to diverge. I've heard of plenty of cofounder disasters.&lt;/p&gt;
&lt;p&gt;But if you look at successful startup founders, even the venerable Jobs and Wozniak, a pattern emerges. Every good pair of founders needs to have what I call a &quot;Nappy Boy&quot; and a &quot;Pretty Boy&quot;.&lt;/p&gt;
&lt;p&gt;The Pretty Boy is a dreamer and a visionary. He can make you fall in love with the future he has concocted. His foresight is unparalleled but his track record may be spotty. The Pretty Boy may sound like a douchebag &quot;idea guy&quot; but he's not. This persona does not necessarily imply a non-technical person. For example, an engineer Pretty Boy can convince you that a distributed, in-memory streaming database will change the way companies look at their data. &lt;strong&gt;The Pretty Boy looks beyond the status quo.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Nappy Boy is a brilliant pragmatist. His performance is unflailing but he never seems to get the recognition he deserves. While the Nappy Boy may seem like the archetypal basement-dwelling engineer, he can also be a designer or a businessman. A business Nappy Boy finds the market for the Pretty Boy's state-of-the-art creations, finding the perfect messaging and positioning so that it will succeed.&amp;nbsp;&lt;strong&gt;The Nappy Boy transforms visions into the new status quo.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Together, Nappy and Pretty can do amazing things. Pretty provides the strategy, the roadmap for the future, the &quot;what could be&quot;. And Nappy chews down that vision with his keen practical attitude until it becomes something achievable. The key is that they support each other. &lt;strong&gt;The pragmatist helps build the vision and the visionary provides foresight and momentum.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This dynamic can become tense when times are tough at the startup. Like all relationships, some level of tension is perfectly healthy. The key to survival is mutual respect. Nappy should feel safe and trust Pretty's strategy. And Pretty should truly believe that Nappy tactics/expertise is what will make his vision happen.&amp;nbsp;&lt;strong&gt;Magic happens when the Nappy Boy and the Pretty Boy want to tell the same story.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do you know when you've found your perfect counterpart?&lt;/strong&gt; The easiest way is to observe how you and your prospective founder behave during a brainstorm. The dialogue should cycle between periods of enthusiasm and &quot;what-if&quot; and periods of pragmatisms and &quot;here-is-how&quot;. The rhythm feels like two steps forward and one step back every so often. If your trust and respect can withstand the tug of this push-pull mechanism, you might have found the one.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Setting Metrics That Encourage Failure</title>
   <link href="http://sridattalabs.com//setting-metrics-that-encourage-failure"/>
   <updated>2012-01-09T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/setting-metrics-that-encourage-failure</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;I've been using a nifty app called &lt;a href=&quot;http://chains.cc/&quot;&gt;Chains&lt;/a&gt; to keep track of my New Year's resolutions. It is based on &lt;a href=&quot;http://lifehacker.com/281626/jerry-seinfelds-productivity-secret&quot;&gt;Jerry Seinfeld's principle of &quot;Don't Break the Chain,&quot;&lt;/a&gt; in which you strive to accumulate as many consecutive days of keeping to a certain habit. The idea is that the longer your &quot;chain&quot; becomes, the more impetus you have to not break it.&lt;/p&gt;
&lt;p&gt;Chains has been working wonders for me so far. I don't get the same nagging feeling I get with a to-do list or a task manager. In fact, the small act of adding one more link to my chain of habits is incredibly gratifying.&lt;/p&gt;

&lt;img src=&quot;/public/chains1.png&quot; /&gt;

&lt;p&gt;However, I noticed a small lapse in judgement as I was using this tool. The problem was that the gratification of adding links to a chain was almost too much. I broke my promise to sleep by midnight last night but before I hit the hay, I impulsively clicked &quot;Done&quot; on my &quot;Sleep By Midnight&quot; habit.&lt;/p&gt;
&lt;p&gt;Pretty soon I realized what I had done but instead of immediately undoing it, I entertained the notion of simply leaving it. If I didn't build up my chain, it felt like a failure. I had to do it, even if it meant that I was lying to myself; it just felt too good.&lt;/p&gt;
&lt;p&gt;I had the equinamity to force myself to be honest. But I realized that the problem with every metric is that sooner or later, you begin to pander to the metric rather than working on what the metric is actually trying to measure.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If the performance is self-reported, you become tempted to lie. Otherwise, you can still do a sloppy job in order to meet short term goals. For example, a salesman can too agressively upsell to existing customers to meet monthly sales goals, which damages his goodwill with them and might lose him the account later on.&lt;/p&gt;

&lt;img src=&quot;/public/chains2.png&quot; /&gt;

&lt;p&gt;What is the solution? For this particular scenario, I ensured that there was a meta-metric -- a chain called &quot;Being honest on Chains&quot;. Regardless of how many habits I kept or failed on a given day, I knew that as long as I answered honestly I would get to click &quot;Done&quot; on the honesty chain. And while it meant accepting my failures, it also meant I was staying true to my ulterior goal of self-improvement.&lt;/p&gt;
&lt;p&gt;This technique can possibly be applied at the workplace, with teams or anywhere performance is measured. The first step is to realize that a measurement is a proxy for what really matters. Attaching too much importance to it makes it a system to be gamed.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It is wise to measure failures, attempts and effort without fear of penalty. Not only does it increase honesty &amp;nbsp;-- because it feels far better to fill in a failure than to not be able to put down anything at all -- but it also gives more granular information to analyze.&lt;/p&gt;
&lt;p&gt;Thoughts? Leave a line in the comments.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Testing Out Syntax Highlighting</title>
   <link href="http://sridattalabs.com//testing-out-syntax-highlighting"/>
   <updated>2012-01-08T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/testing-out-syntax-highlighting</id>
   <content type="html">&lt;p&gt;I have a tendency to wax philosophical on this blog so I am hoping to bring a new sense of pragmatism by posting &quot;real-world&quot; things such as code snippets and tutorials. To help with this, I've installed &lt;a href=&quot;http://alexgorbatchev.com/SyntaxHighlighter/&quot; target=&quot;_blank&quot;&gt;a syntax highlighting script&lt;/a&gt; on my page.&lt;/p&gt;
&lt;p&gt;Let's see if this works:&lt;/p&gt;
&lt;pre class=&quot;brush: java; toolbar: false&quot;&gt;public static void main(){
  System.out.println(&amp;quot;Hello World&amp;quot;);
}&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>How to Achieve Everything You Want With Zero Discipline</title>
   <link href="http://sridattalabs.com//how-to-everything-you-want-with-zero-discipli"/>
   <updated>2011-11-28T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/how-to-everything-you-want-with-zero-discipli</id>
   <content type="html">&lt;p class=&quot;p1&quot;&gt;Traditional life coaches think you are too weak to be able to accomplish multiple things at once. Common wisdom says you should &lt;a href=&quot;http://zenhabits.net/really-simple-goal-setting/ &quot; target=&quot;_blank&quot;&gt;only try training for one goal at a time&lt;/a&gt; so you don't run out of motivation.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;That's complete nonsense. In fact, there are millions people who specialize in training for painfully rigorous things, not just one at a time but in batch. They aren't extraordinary super-achievers; they are ordinary college students. An undergraduate student takes 3-4 courses during a single term. Mastering these courses is no mean feat but, as a whole, most students are able to complete each term with at least &lt;em&gt;satisfactory&lt;/em&gt; acheivement in each topic of study.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;How are they able to do this while the average person can hardly make progress on one or two of their goals?&amp;nbsp;The secret is an effective syllabus, designed by experts.&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;Good training requires some source of rigor. Traditional goal-setting places this burden on the the learner.&amp;nbsp;Let's take for example a beginner runner whose goal is to &quot;be able to complete a 10K in 60 minutes&quot;. Even with this well-defined goal, it is up to the learner to fill in the blanks on how to get there. Most people just &quot;get out there&quot; and &quot;practice&quot;.&amp;nbsp; They may burn out by trying to do too much too quickly. They might encounter weeks of zero improvement. Pushing through these rough patches requires expending willpower, &lt;a href=&quot;http://www.nytimes.com/2010/10/09/your-money/09shortcuts.html&quot; target=&quot;_blank&quot;&gt;which is a limited resource&lt;/a&gt;.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;Compare that method to a syllabus &lt;a href=&quot;http://blog.bluefinapps.com/about-bridge-to-10k/&quot; target=&quot;_blank&quot;&gt;Bridge to 10K program&lt;/a&gt;. By following a syllabus, you are practically guaranteed to make meaningful progress with each training session. Sessions are designed to improve on or sustain the result of the previous session. But it is not just &lt;em&gt;any &lt;/em&gt;progress; a good syllabus ensures that progress is being made at a &lt;em&gt;sustainable&lt;/em&gt; rate. This reduces the issue of burn-out or plateauing.&amp;nbsp; They also provide a well defined metric of success, for immediate feedback. An perhaps most importantly, a syllabus provides a timeframe so that the goal does not become a perpetual one.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;&lt;strong&gt;A syllabus ensures that you make progress just by &quot;showing up&quot; and doing what it tells you.&lt;/strong&gt;&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;Now all the rigor has been offloaded from the learner to the syllabus itself. Since each goal barely taxes your fixed bank of willpower, you are free to pursue as many as you have time for. If you have time in your schedule to allot to a given training program, you can tack that onto your list of goals.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;So next time you set a goal, find a syllabus/training program to accompany it. A lot of forums provide such &quot;[X] Week beginner programs&quot; as sticky posts. On Reddit.com's mini-sites (called &quot;subreddits&quot;), helpful step-by-step tutorials can be found in the sidebar. And remember that if a college kid can learn 4 things at once, so can you.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hidden Elegance of the JVM  </title>
   <link href="http://sridattalabs.com//hidden-elegance-of-the-jvm"/>
   <updated>2011-09-19T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/hidden-elegance-of-the-jvm</id>
   <content type="html">&lt;p class=&quot;p1&quot;&gt;Last week, I wrote a (botched) attempt to run supervised user-generated code on the JVM. (It's a cardinal sin, I know, I know). In the process, I wrote several hooks into the JVM runtime to make sure the insecure code was not attempting to use unsafe features. (If you're curious, it involved custom class loaders and security managers).&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;It dawned on me that I was writing a Java program that was modifying the runtime that was executing it. It was reminiscent of Lisp macros and the metacircular evaluator in SICP. It's not quite on the same level as Lisp's homoiconicity but more elegance that I would expect from kludgy Java.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;Programs that are able to reason about their own execution fascinate me.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>What Computer Geeks Really Do: A Guide for Friends, Family and Humanities Students</title>
   <link href="http://sridattalabs.com//what-computer-geeks-really-do-a-guide-for-fri"/>
   <updated>2011-09-18T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/what-computer-geeks-really-do-a-guide-for-fri</id>
   <content type="html">&lt;p class=&quot;p1&quot;&gt;People like me are widely misunderstood. I am disappointed when people think of computer geeks as practitioners of soulless, mechanical endeavors. I like to think of what I do as an art and a craft. Yet I agree my job is steeped in arcane acronyms and daunting terminology that makes it seem like a form of witchcraft for geniuses.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;As ubiquitous as computers are today, the layperson probably has a more intuitive understanding of the esoteric job of woodwork/carpentry. So to help friends, family, and humanities students what I do, I will draw the parallels between my occupation and those of woodworkers:&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;&lt;strong&gt;The Artisan&lt;/strong&gt;&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;An artisan is involved in the aesthetic and usefulness of a piece of work. If the task was to build a chair, the artisan would make sure that the chair was comfortable to sit in, could be stowed away conveniently and would be pleasing to look at.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;This computer analogue of that artisan is a &quot;designer&quot; or &quot;hacker.&quot; They have good knowledge of computers and programming but their job is not to think about that. They instead think about whether the overall product is usable for the final user.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;&lt;strong&gt;The Builder&lt;/strong&gt;&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;The builder's speciality is in the precision and skill of his hands. He is the one who carves raw lumber into a useful piece of wood. A builder prides himself in making this transformation while producing as little scrap wood as possible and using the fewest cuts.&amp;nbsp; He turns the craftsman's schematics into reality.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;This is most like the job of a &quot;programmer&quot; or &quot;developer&quot;. This type of work is the one that immediately comes to mind when thinking of computers. Programmers write computer code that makes different pieces of software do their bidding. To do this efficiently requires attention to detail and experience.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;&lt;strong&gt;The Craftsman&lt;/strong&gt;&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;The craftsman is concerned with the structure of the work. He concerns himself with finding out the strength and suitability of different woods, the load-bearing capabilities of nails and fasteners, and the overall stability of frames. A craftsman innovates by exploiting the capabilities of these components in novel ways.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;In the computer world, such people may be known as &quot;computer engineers&quot; or &quot;software engineers&quot; (they are rather different, but that is not important here). They quantify the behavior of the underlying components of the whole and how to efficiently put them together. Like scientists, they collect data and metrics but they are involved in the practice more than pure theory.&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;&lt;strong&gt;The Scientist&lt;/strong&gt;&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;Imagine if botanists who study tree composition started calling themselves &quot;woodworkers&quot;. It is true that some discovery about the biology of oak trees could possibly benefit the construction of furniture. But the relation is not immediate.&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;Similarly, &quot;computer scientists&quot; are mathematicians masquerading as people that work with computers. The imaginary computers they study run on proofs and formulas, not hardware and code like real computers. Many of their discoveries advance the field in practical ways but not in ways that are immediately apparent.&lt;/p&gt;
&lt;p class=&quot;p2&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;p1&quot;&gt;It's rare that a geek falls squarely into exactly one of these categories. It's not even a spectrum &lt;em&gt;per se&lt;/em&gt;. For example, I am an &quot;artisan&quot; and an &quot;craftsman&quot; but my code is not particularly good, so I'm not a &quot;builder&quot;.&lt;/p&gt;
&lt;p&gt;For more sagely advice on the spectrum of occupations within &quot;computers&quot;, read the Paul Graham's famous essay, &lt;a href=&quot;http://www.paulgraham.com/hp.html&quot;&gt;Hackers and Painters&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Frightening Return of Walled Gardens</title>
   <link href="http://sridattalabs.com//the-frightening-return-of-walled-gardens"/>
   <updated>2010-09-05T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/the-frightening-return-of-walled-gardens</id>
   <content type="html">&lt;p&gt;Everyone who used the Internet in the 1990s remembers the ubiquity of &quot;AOL Keywords.&quot; They were short phrases that served as proprietary URLs within the AOL portal; for instance, you could navigate to the cryptic &quot;&lt;a href=&quot;http://www.oprah.com&quot;&gt;http://www.oprah.com&lt;/a&gt;&quot; or you could simply type &quot;OPRAH&quot; into your AOL keyword bar and be taken directly Oprah's special page hosted on the AOL network. Guess which one most people used?&lt;/p&gt;
&lt;p&gt;Given the popularity of America Online as an ISP, its web portal tended to be the center of the layman's web browsing experience. &lt;a href=&quot;http://www.help4web.net/webmaster/KeywordListA-Z.html&quot;&gt;Everything you could ever need&lt;/a&gt;&amp;nbsp;was found with AOL's carefully administered walled garden, so the casual web user really had no experience with the World Wide Web at large. For big businesses, this fact meant that it was crucial to establish an AOL keyword so they could be found by the quarantined masses of AOL customers.&lt;/p&gt;
&lt;p&gt;The public's eventual awareness of the rest of the free and open Internet was precipitated by the &quot;.com&quot; boom, better search engines and the demise of AOL. But it seems we are taking a step back to the Dark Ages of the 90s. Facebook fan pages have usurped AOL Keywords as the modern alternative to the publicly accessible Internet. You rarely see organizations publicizing their webpages anymore. These days, they just say &quot;Become a fan of [whatever] on Facebook&quot;.&lt;/p&gt;
&lt;p&gt;The parallels are frightening. Like the AOL network, Facebook is entirely proprietary. All content hosted on Facebook is only accessible by people who have signed up to be members of the site, just like AOL's web portal was only available to its subscribers. Today it is still possible to find copies of regular webpages that have been up since 1995. But there is little to no record of the pages that were hosted on the AOL network from that time. The same will happen to pages on the Facebook network if the social media giant were to crash.&lt;/p&gt;
&lt;p&gt;I don't wear a tinfoil hat and try to live off the social media grid. I have plenty of my own data locked up in Facebook's proprietary social graph. But I will readily admit that these closely guarded walled gardens are subverting the Internet ecosystem, depriving it of content that is meant to be freely accessible through open standards. Perhaps we should consider that for posterity.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>You're Only As Good As Others Say You Are</title>
   <link href="http://sridattalabs.com//youre-only-as-good-as-others-say-you-are"/>
   <updated>2010-08-28T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/youre-only-as-good-as-others-say-you-are</id>
   <content type="html">&lt;p&gt;This &lt;a href=&quot;http://floodlite.tumblr.com/post/1011047822/apples-attention-to-detail&quot;&gt;little tidbit&lt;/a&gt;, entitled &quot;Apple's Attention to Detail,&amp;nbsp;has been making rounds around the Internet recently. It describes how the Mac sleeping indicator blinks in a way that emulates human breathing patterns. &amp;nbsp;I am skeptical if it is really a great example of attention to detail. This kind of &quot;subliminal messaging&quot; gets bandied about in design huddles everywhere. &quot;Let's make the background silhouette more curvaceous so it invokes ideas of attractive women!&quot; or &quot;We should make the Purchase button green because green means 'go'!&quot; We've heard it all.&lt;/p&gt;
&lt;p&gt;But what &lt;em&gt;is&lt;/em&gt;&amp;nbsp;remarkable is the eagerness of Apple fans and product designers to correlate this interesting-yet-unremarkable idea with Apple's design prowess. The company's success is not in doing revolutionary things but rather in getting people to talk about them as if they were.&amp;nbsp;This post isn't supposed to be about technology. But the Apple example above demonstrates a larger point that applies to you and me.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The fact is that most of us are not significantly better than our colleagues and competitors, despite our &lt;a href=&quot;http://en.wikipedia.org/wiki/Illusory_superiority&quot;&gt;cognitive bias&lt;/a&gt; indicating otherwise. I know that I am certainly not; I have classmates who can score better grades with less effort and hacking buddies who can whip up prototypes faster than I can. But I am generally believed to be smarter and more talented than I really am. The trick is that the people around me do a better job of building my reputation than I ever can. I've had an acquaintance who I barely remembered excitedly introduce me as his most &quot;interesting and genuine friend.&quot; I've gotten to work on some interesting projects because my friend made sure my reputation preceded me.&lt;/p&gt;
&lt;p&gt;The secret to success is to get people to talk about you, whether &quot;you&quot; are a billion-dollar corporation or a sophomore in college. How do you ensure this? I doubt I could enumerate the steps myself but Dale Carnegie's &lt;a href=&quot;http://www.amazon.com/How-Win-Friends-Influence-People/dp/0671723650&quot;&gt;How to Win Friends and Influence People&lt;/a&gt;&amp;nbsp;suggests that simply being receptive and interested in others does wonders to their impression of you.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>An Experiment in Simplicity</title>
   <link href="http://sridattalabs.com//26073165"/>
   <updated>2010-08-19T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/26073165</id>
   <content type="html">&lt;blockquote class=&quot;gmail_quote&quot; style=&quot;margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: #cccccc; border-left-style: solid; padding-left: 1ex;&quot;&gt;&amp;nbsp;Our inventions are wont to be pretty toys, which distract our attention from serious things. They are but improved means to an unimproved end. - Henry David Thoreau, Walden&amp;nbsp;&lt;/blockquote&gt;
&lt;p&gt;Like Thoreau, I've decided to leave behind the trappings of modernity&amp;mdash; in my web apps, at least. For my next project, I am setting out to build the simplest idea that will actually make me money. For once (and it pains me to say this), I won't focus on building innovative technology. My goal is to push out a minimum viable product that will generate revenue. I'm giving myself no more than 4 hours to make this happen&lt;/p&gt;
&lt;p&gt;Let's get down to business.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Why Being A Techie Is Ruining Your Products</title>
   <link href="http://sridattalabs.com//why-being-a-techie-is-ruining-your-products"/>
   <updated>2010-08-18T00:00:00+00:00</updated>
   <id>http://sridattalabs.com/why-being-a-techie-is-ruining-your-products</id>
   <content type="html">&lt;p&gt;If you are reading this blog, chances are that you describe yourself as a technology enthusiast. But all these things could be preventing you from building. Like many of you, I face the problem of being overimmersed in tech culture. My RSS reader has me reading 12 different tech blogs daily and I've probably played around with every reasonably stable development tools released in the last 2 years. But at one point, this quickly became a problem.&lt;/p&gt;
&lt;p&gt;To me, technology itself became something inherently wondrous and beautiful. Products were amazing because they implemented the latest and greatest tech, not because they did anything particularly profound. Futhermore, my empathy toward other developers was clouding my judgement. I forgave that clunkiness and quirks of the web-apps I saw being posted all over the internet; after all, I knew how much effort it must have taken them and it wouldn't be fair to judge them too harshly.&lt;/p&gt;
&lt;p&gt;What resulted was a sense of disconnection from what technology means to most people. I realized it when I was showing my best friend in Massachusetts a web app I created for a hackfest. There seemed to be a fundamental difference between what I what I thought was important to present to her and what she cared to hear about. This was true among the others I showed it to as well.&lt;/p&gt;
&lt;p&gt;I don't mean to exaggerate the divergence between the techies and the regular people. Even those who frequent tech blogs have a sense of what is resonable, and the general populace does have a sense of fascination with fancy tech. But with Slashdot, Hackernews and other tech sites, we have created an industry-wide hype machine that distorts our perception of what makes good products.&lt;/p&gt;
&lt;p&gt;Here's some tough love to keep you from becoming overimmersed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make sure you're not just building a tech demo. While building the first webapp that uses Clojure to program a Hadoop cluster that processes data from Facebook's Graph API may get you tweeted about, your end user only cares about what the product can do for him. No bleeding-edge technology is going to make up for the lack of a compelling set of features. Conversely, no one is going to stay away from a killer application even if it was programmed in VBscript.&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Don't build a Swiss Army knife. Geeks love LOTS of little features. The most popular sites making rounds on the blogosphere have SMS integration, Twitter, a Firefox plugin, etc. However, real users prefer to look back at the big picture and see whether your app provides a cohesive experience. Its not about the features themselves but rather how they work together to provide value.&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;Prepare to be underappreciated. You know that polishing a product take months and that even trivial applications take hundreds of lines of code. But they don't. People simply expect computer technology to do amazing things out of the box and become better over time. If your product is not significantly better than what your users were using 6 months ago, there is no reason for them to switch. Very few people outside the techie crowd are used to using fly-by-night Web 2.0 applications. When the average person sees your site, they will likely compare it to polished, mature products like Gmail. Make sure you have the same &quot;WOW&quot; factor.&lt;/li&gt;
&lt;/ol&gt;
</content>
 </entry>
 
 
</feed>
