<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rinesi.net</title>
	<atom:link href="http://rinesi.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://rinesi.net</link>
	<description>Marcelo Rinesi&#039;s not-overly-personal blog</description>
	<lastBuildDate>Mon, 08 Mar 2010 05:21:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Python jobs &#8212; quantifying what we more or less already knew</title>
		<link>http://rinesi.net/2010/03/python-jobs-quantifying-what-we-more-or-less-already-knew/</link>
		<comments>http://rinesi.net/2010/03/python-jobs-quantifying-what-we-more-or-less-already-knew/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 04:38:32 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[data analysis]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=50</guid>
		<description><![CDATA[I dedicated a couple of hours during the weekend to (gently) spidering a well-known online jobs site in Argentina for Python-related positions, and then running hierarchical cluster analysis on hand-selected keywords using Pycluster.
According to this analysis (with all the caveats about rushed work, low n, etc), there are roughly three differentiated &#8220;domains of competence&#8221; according [...]]]></description>
			<content:encoded><![CDATA[<p>I dedicated a couple of hours during the weekend to (gently) spidering a well-known online jobs site in Argentina for Python-related positions, and then running hierarchical cluster analysis on hand-selected keywords using <a href="http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/software.htm">Pycluster</a>.</p>
<p>According to this analysis (with all the caveats about rushed work, low n, etc), there are roughly three differentiated &#8220;domains of competence&#8221; according to the people who write posts in job boards: </p>
<ul>
<li>A &#8220;narrow web domain&#8221;:  <em>ajax, dhtml, hibernate, apache, tomcat, spring, corba, rails, java, ruby, perl, php</em></li>
<li>A &#8220;wide web domain&#8221;:<em>html, javascript, css, xml, mysql, cms, xhtml, c, cctv, ethernet, django, turbogears, flex, flash, coldfusion, xslt, lamp, mssql, soap, clusters, hpc, jboss, jetty, subversion, snmp, samba, excel, sybase, smarty, postgresql, rpc, plone, openerp, zope</em></li>
<li>A &#8220;server domain&#8221; (more sharply distinct from the rest):<em> c++, boost, dns, firewalls, jython, unix, oracle, sql, solaris, ip, api, tcp, openssl, linux, svn</em></li>
</ul>
<p>The labels I chose are of course largely arbitrary, but the grouping itself is less so, and not obviously derived from technological reasons. The &#8220;server domain&#8221; is more or less self-explanatory (although not devoid of weirdness), but why are the two first categories grouped as they are? Off the top of my head, I think that this reflects the existence of a more programming-oriented web domain among Python-mentioning jobs where dynamic languages are notorious and relatively large deployments are expected (hence the &#8220;enterprise&#8221; java technologies), and a large and heterogeneous &#8220;bag domain&#8221; of web-related technologies where everything goes. Needlessly to say, this description falls apart quite quickly (&#8220;clusters&#8221; and &#8220;hpc&#8221; belong to this bag domain, where they should logically go somewhere else), but, still, it seems to be a workable first approximation.</p>
<p>Looking at a finer granularity, things become much clearer. You have, for example, a &#8220;dynamic languages&#8221; cluster, and a very well defined &#8220;classic websites&#8221; cluster (<em>html, javascript, css, xml, mysql</em>).</p>
<p>It would be interesting to see how well these clusters (specially at the finer granularity levels) correlate with actual demands during work, but I&#8217;m not sure where to get that data from.</p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/03/python-jobs-quantifying-what-we-more-or-less-already-knew/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Picking fonts and colors? Use the force! (of guided evolution)</title>
		<link>http://rinesi.net/2010/03/picking-fonts-and-colors-use-the-force-of-guided-evolution/</link>
		<comments>http://rinesi.net/2010/03/picking-fonts-and-colors-use-the-force-of-guided-evolution/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 00:44:54 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=48</guid>
		<description><![CDATA[A little page straddling the line between toy and tool: mage. Coded quite quickly with Django&#8217;s help, it allows you to explore a bit of the combinatorial space of designs.
]]></description>
			<content:encoded><![CDATA[<p>A little page straddling the line between toy and tool: <a href="http://codexstudio.com/mage">mage</a>. Coded quite quickly with Django&#8217;s help, it allows you to explore a bit of the combinatorial space of designs.</p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/03/picking-fonts-and-colors-use-the-force-of-guided-evolution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On language lock-up being evil</title>
		<link>http://rinesi.net/2010/02/on-language-lock-up-being-evil/</link>
		<comments>http://rinesi.net/2010/02/on-language-lock-up-being-evil/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 03:46:30 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=45</guid>
		<description><![CDATA[So far, what&#8217;s biting me in the ass most often when playing with newLISP is the fact that you have to explicitly control what lists get executed when. It&#8217;s a logical thing, because the interpreter has no way of knowing what lists are data and what lists are code at any given point in time [...]]]></description>
			<content:encoded><![CDATA[<p>So far, what&#8217;s biting me in the ass most often when playing with newLISP is the fact that you have to explicitly control what lists get executed when. It&#8217;s a logical thing, because the interpreter has no way of knowing what lists are data and what lists are code at any given point in time (which is the point of LISP-y languages), but it&#8217;s taking me some effort getting used to that. My old primate brain finds syntactical markings easier to understand (e.g., Python), but that makes hardens the (artificial) barrier between data and code.</p>
<p>Which suggests the question of why the hell should I have to choose? Isn&#8217;t there an IDE that, say, rewrites on the fly a LISP list making educated guesses about what will get applied when? E.g., it could render (inc a) as inc(a), and so on. And it could go the other way around, rendering (I use the word deliberately) the parse tree of Python code into a LISP format that would make it easier to think about and write code manipulation code. I read something about such a project a long while ago, although I have yet to track it back &mdash; essentially, specific languages are conventions to describe computations, so we should be able to render any particular computation into whatever language is most convenient to the task at hand. Compilers do that, which is nice for the CPU, but my brain spends time dealing with programs, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/02/on-language-lock-up-being-evil/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lack of side effects is a red herring</title>
		<link>http://rinesi.net/2010/02/lack-of-side-effects-is-a-red-herring/</link>
		<comments>http://rinesi.net/2010/02/lack-of-side-effects-is-a-red-herring/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 04:37:54 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=39</guid>
		<description><![CDATA[Functional programming is not about lack of side effects. Functional programming is about manipulating code (really, computations/functions/algorithms) instead of, or at least as much as, data. Lack of side effects in functions makes it easier to think about them, but that&#8217;s all. Here&#8217;s a good example of what thinking functionally looks like.
For a much worse [...]]]></description>
			<content:encoded><![CDATA[<p>Functional programming is not about lack of side effects. Functional programming is about manipulating code (really, computations/functions/algorithms) instead of, or at least as much as, data. Lack of side effects in functions makes it easier to think about them, but that&#8217;s all. <a href="http://research.sun.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf">Here&#8217;s a good example of what thinking functionally looks like.</a></p>
<p>For a much worse example, <a href="http://pastebin.com/f57abce64">here</a> is a quick and brain-dead version of &#8220;apply&#8221; I just wrote that allows you to do things like</p>
<p><code><br />
dataparser = [ stripped, split(','), (str, int, capitalized) ]<br />
for line in datafile:<br />
&nbsp;&nbsp;&nbsp;&nbsp;print apply(dataparser, line)<br />
</code></p>
<p>The important lines are the last three; once you have your basic functions (and leaving aside questions of arity, debugging, types, and such), you shouldn&#8217;t need to write scaffolding code in order to compose them in simple ways. In this example, the <code>dataparser = [ stripped, split(','), (str, int, capitalized) ]</code> line simply says &#8220;this is the function that applies <i>stripped</i>, then <i>split(&#8216;,&#8217;)</i>, and then <i>str</i>, <i>int</i>, and <i>capitalized</i> to each of the three elements of the result tuple.&#8221; There&#8217;s a large number of simple scripts that use this sort of process a lot, and I feel that even if it&#8217;s not really that much of an issue to explicitly define the composed function, it compounds over a large number of tasks, and subtly discourages reuse of components and strategies and, most importantly, makes it subtly harder to work over the process.</p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/02/lack-of-side-effects-is-a-red-herring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>newLISP</title>
		<link>http://rinesi.net/2010/02/newlisp/</link>
		<comments>http://rinesi.net/2010/02/newlisp/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 04:29:20 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[newlisp]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=36</guid>
		<description><![CDATA[I&#8217;ve been playing with newLISP. So far so good; it&#8217;s a relatively simple   LISP with more batteries included than the usual. Python is still my main development language, but I&#8217;m willing to sink some time into newLISP, to see if I can get properly enlightened. For all of the language&#8217;s elegance in most [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing with <a href="http://www.newlisp.org/">newLISP</a>. So far so good; it&#8217;s a relatively simple   LISP with more batteries included than the usual. Python is still my main development language, but I&#8217;m willing to sink some time into newLISP, to see if I can get properly enlightened. For all of the language&#8217;s elegance in most contexts, Python metaprogramming is indeed kludgy. </p>
<p>By the way, I think Ruby is more powerful in this regard, although still not elegant at all. And, as EWD would say, elegance is nothing else but another word for conceptual usability; inelegant tools lead to solutions that cannot be understood by either designers or implementators; lack of understanding leads to undying bugs, unsound algorithms, and multi-decade technological dead-ends.</p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/02/newlisp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Computing progress doesn&#8217;t always</title>
		<link>http://rinesi.net/2010/02/computing-progress-doesnt-always/</link>
		<comments>http://rinesi.net/2010/02/computing-progress-doesnt-always/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 03:39:02 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=34</guid>
		<description><![CDATA[Been using a tiling window manager (Ion) for less than a day now, already feels more natural than any other window management system I&#8217;ve ever used. 
It&#8217;s sad that we have spent so much time fiddling with useless functionality in software, that taking out flexibility actually improves your productivity.
]]></description>
			<content:encoded><![CDATA[<p>Been using a tiling window manager (<a href="http://modeemi.fi/~tuomov/ion/">Ion</a>) for less than a day now, already feels more natural than any other window management system I&#8217;ve ever used. </p>
<p>It&#8217;s sad that we have spent so much time fiddling with useless functionality in software, that taking out flexibility actually improves your productivity.</p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/02/computing-progress-doesnt-always/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hijacking Django</title>
		<link>http://rinesi.net/2010/02/hijacking-django/</link>
		<comments>http://rinesi.net/2010/02/hijacking-django/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 02:06:33 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=32</guid>
		<description><![CDATA[Hacking the Django admin is both bad form and, at times, a great time saver. As this post shows, subclassing admin.ModelAdmin can get you very far, specially if (unlike in that post), you go beyond save_model and start wrapping and replacing other methods of the base class (e.g., you can wrap form generation to preload [...]]]></description>
			<content:encoded><![CDATA[<p>Hacking the Django admin is both bad form and, at times, a great time saver. As <a href="http://www.b-list.org/weblog/2008/dec/24/admin/">this post</a> shows, subclassing <tt>admin.ModelAdmin</tt> can get you very far, specially if (unlike in that post), you go beyond <tt>save_model</tt> and start wrapping and replacing other methods of the base class (e.g., you can wrap form generation to preload useful dynamic values &mdash; and why the hell don&#8217;t <tt>default</tt> callables take arguments?). The obvious use case is creatively restricting what admin users can do (yes, I know, not what the admin is there for&#8230; or so we are told), but you can do very arbitrarily funny things. </p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/02/hijacking-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A pythonic monad example</title>
		<link>http://rinesi.net/2010/02/a-pythonic-monad-example/</link>
		<comments>http://rinesi.net/2010/02/a-pythonic-monad-example/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 02:52:51 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=27</guid>
		<description><![CDATA[Let&#8217;s implement the classic &#8220;Maybe&#8221; monad, for simple functions.
Pastebin link
]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s implement the classic &#8220;Maybe&#8221; monad, for simple functions.</p>
<pre class="chili"><code class="python""">
#!/usr/local/bin/python

class Undefined:
    pass

class Maybe:
    def __init__(self, x=Undefined):
        self.value = x

    def apply(self, f):
        if not self.is_defined:
            return Maybe()
        else:
            return Maybe(f(self.value))

    def __repr__(self):
        if not self.is_defined:
            return &#039;&lt;Undefined&gt;&#039;
        else:
            return repr(self.value)

    @property
    def is_defined(self):
        return not self.value is Undefined

def monad_aware(f):
    def fprime(x):
        return x.apply(f)
    return fprime

if __name__ == &#039;__main__&#039;:

    @monad_aware
    def double(x):
        return 2*x

    x = Maybe()
    print double(x)
    assert(not double(x).is_defined)

    x = Maybe(2)
    print double(x)
    assert(double(x).is_defined)
    assert(double(x).value == 4)

</code></pre>
<p><a href="http://pastebin.com/f7bd884d3">Pastebin link</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/02/a-pythonic-monad-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finally groked monads (in the programming context)</title>
		<link>http://rinesi.net/2010/02/finally-groked-monads-in-the-programming-context/</link>
		<comments>http://rinesi.net/2010/02/finally-groked-monads-in-the-programming-context/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 03:06:44 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=24</guid>
		<description><![CDATA[Long story short: When you apply a function to a value, the function controls the process. When you apply a function to a monad, the monad controls the process. That is what allows monads to extend the semantics of functions (e.g., adding side effects, or whatever). 
And why not? Why should values be passive? (Note [...]]]></description>
			<content:encoded><![CDATA[<p>Long story short: <i>When you apply a function to a value, the function controls the process. When you apply a function to a monad, the monad controls the process.</i> That is what allows monads to extend the semantics of functions (e.g., adding side effects, or whatever). </p>
<p>And why not? Why should values be passive? (Note that accessors are a bit like half-monads; but full monads can  do whatever the hell they want with functions, way beyond playing with what they see.)</p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/02/finally-groked-monads-in-the-programming-context/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#8217;m not sure if this is deep, trivial, or both</title>
		<link>http://rinesi.net/2010/01/im-not-sure-if-this-is-deep-trivial-or-both/</link>
		<comments>http://rinesi.net/2010/01/im-not-sure-if-this-is-deep-trivial-or-both/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 04:25:48 +0000</pubDate>
		<dc:creator>Marcelo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[physics]]></category>

		<guid isPermaLink="false">http://rinesi.net/?p=21</guid>
		<description><![CDATA[
[Very simple abstract setup, describing an ensemble of physical systems through a probability distribution over phase space, and dynamics by a differential equation.] Then, the well-known Liouville equation describes the dynamics of this distribution. For this type of evolution the Kullback-Leibler information measure provides a convenient way to measure the distance between two distinct probability [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
[Very simple abstract setup, describing an ensemble of physical systems through a probability distribution over phase space, and dynamics by a differential equation.] Then, the well-known Liouville equation describes the dynamics of this distribution. For this type of evolution the Kullback-Leibler information measure provides a convenient way to measure the distance between two distinct probability distributions P1 and P2 because, remarkably, it is invariant under dynamical changes prescribed by the Liouville equation.
</p></blockquote>
<p>I&#8217;m not a physicist, but I feel compelled to annotate that &mdash; in the style of chess games &mdash; with a <b>(!)</b> (although I don&#8217;t think this is really a physics result). The Kullback-Leibler is a well-known (if not <i>the</i>) information distance between distributions, but I had no idea that it was preserved by such a wide range of dynamic systems.</p>
<p><a href="http://dare.ubvu.vu.nl/bitstream/1871/10137/1/L59.pdf">Classical No-Cloning Theorem</a></p>
]]></content:encoded>
			<wfw:commentRss>http://rinesi.net/2010/01/im-not-sure-if-this-is-deep-trivial-or-both/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
