<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>/var/log/mind</title>
	
	<link>http://blog.dhananjaynene.com</link>
	<description>Dhananjay Nene's opinions on software programming, design, architecture and the internet</description>
	<lastBuildDate>Sat, 21 Jan 2012 12:52:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/var/log/mind" /><feedburner:info uri="var/log/mind" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><feedburner:emailServiceId>var/log/mind</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Conference Report – Hasgeek jsFoo Pune 2012</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/1KFZ41RXF30/</link>
		<comments>http://blog.dhananjaynene.com/2012/01/conference-report-hasgeek-jsfoo-pune-2012/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 12:52:36 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[hasgeek]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jsfoo]]></category>
		<category><![CDATA[pune]]></category>

	<!-- AutoMeta Start -->
	<category>jsfoo</category>
	<category>hasgeek</category>
	<category>jasmine</category>
	<category>async</category>
	<category>sync</category>
	<category>websockets</category>
	<category>thruput</category>
	<category>backbone</category>
	<category>jsfoo</category>
	<category>hasgeek</category>
	<category>jasmine</category>
	<category>async</category>
	<category>sync</category>
	<category>websockets</category>
	<category>thruput</category>
	<category>backbone</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1221</guid>
		<description><![CDATA[Just finished attending jsFoo Pune 2012 organised by HasGeek. It was an interesting and a well spent day. And I&#8217;ve learnt if one wants to blog about a conference, it is best done immediately post the event else much gets lost with a recollection as weak as mine. The conference was spread over 3 tracks. [...]]]></description>
			<content:encoded><![CDATA[<p>Just finished attending <a href="http://jsfoo.in/pune2012/">jsFoo Pune 2012</a> organised by <a href="http://hasgeek.com/">HasGeek</a>. It was an interesting and a well spent day. And I&#8217;ve learnt if one wants to blog about a conference, it is best done immediately post the event else much gets lost with a recollection as weak as mine.</p>
<p>The conference was spread over 3 tracks. So the best I can do is talk about the talks I attended. </p>
<p>The first talk I attended was <a href="http://funnel.hasgeek.com/jsfoo-pune/179-node-js-html5-and-phoegap-for-high-performant-content-site-app">Node.js, HTML5 and Phonegap for high performant content site app</a> by <a href="https://twitter.com/#!/prasoonk">Prasoon Kumar</a>. I learnt some stuff about <a href="http://phonegap.com/">phonegap</a> and <a href="http://the-m-project.org/friends/espresso/">espresso</a>. Good starting point, but hardly got to see any actual code. </p>
<p>Next one was <a href="http://funnel.hasgeek.com/jsfoo-pune/106-synchronized-models-using-backbone-sockets-and-node">Synchronized models using Backbone, Sockets and Node</a> by Ruben Stolk. He started up a demo and suggested that people in the room connect to it. It basically had a canvas with a image and amongst many things, one could turn the light on the light-stand on and off .. and any actions propagated to the backend and then to all the connected clients. Similarly with post-it kind of notes that one added on the canvas. Was a good example of using backbone for defining models both on the client and the server and using socket.io to stream events between the two. He went through a fair amount of code too and it was very understandable. I came back with a distinct impression that the model maintenance and ability to synchronise the model changes between a client and server and then between the server and all connected clients (thus in effect across all connected clients) was pretty cool. However I still felt there needed a fair degree of wiring up of the event related code, though I am not sure about it and need to experiment with it more.</p>
<p>The next one was <a href="http://funnel.hasgeek.com/jsfoo-pune/181-how-to-apply-bdd-and-tdd-practices-using-jasmine-library">How to apply BDD and TDD practices, using Jasmine library?</a> by Anil Tarte. Anil and I have been colleagues in the past and I have a high respect for his skills. In the brief period he was able to convey how to use <a href="http://pivotal.github.com/jasmine/">jasmine</a> to write BDD Test cases for the client side code. His server was over web sockets, and he was essentially intercepting calls into specific methods that eventually communicated with the backend. He also mentioned it would be possible to intercept the over the wire HTTP traffic instead of javascript functions, though it would create more difficulties if one was not able to precisely control the server&#8217;s outputs. I quite frankly had not imagined that BDD could be used so effectively and especially localised strictly to the client. So it was an insightful talk, that definitely will have me thinking about javascript BDD the next time. However he did seem rushed and under pressure and perhaps the talk lengths could be extended from the 45 mins to 55 mins or so.</p>
<p>Next was <a href="http://funnel.hasgeek.com/jsfoo-pune/175-building-real-time-web-applications-introduction-to-websockets-socket-io">Building real-time web applications &#8230; (Introduction to Websockets / Socket.IO)</a> by <a href="https://twitter.com/#!/netroy">Aditya Y</a>. He talked a bit about evolution of websockets, various libraries that were developed along the way and the current state of websockets support. There was an interesting demo at the end where changes in one browser session were almost being reflected in real time into another browser session via websockets connections back to the server. One of the important points noted was that Websockets continues to ride over port 80 so can work across many firewalls, and while its initial handshake is HTTP like, the subsequent traffic is essentially TCP like over that HTTP connection.</p>
<p>A thoroughly enjoyable talk was <a href="http://funnel.hasgeek.com/jsfoo-pune/170-advanced-javascript-techniques">Advanced JavaScript Techniques</a> by <a href="https://twitter.com/#!/avranju">Rajasekharan Vengalil</a>. He looked like he had enough stuff to talk about for the whole day, and delved into some of the OO related aspects of Javascript and the additions to ECMAScript 5. He spent some good amount of time in explaining how prototype based languages work. There are just so many intricacies to the language and so many really strange behaviours (like silently ignoring assignments etc.) that if I hated the language I would&#8217;ve just continuously muttered WTFs and if I happened to passionately like the language, I just might&#8217;ve facepalm&#8217;ed my way through the talk. Thankfully my outlook towards javascript is quite neutral, so I just enjoyed it . A lot.</p>
<p><a href="http://funnel.hasgeek.com/jsfoo-pune/162-node-js-patterns-and-how-we-build-activenode">Node.js Patterns and How we build ActiveNode</a> was the next talk by <a href="https://twitter.com/#!/sreeix">Sreekanth Vadagiri</a>. He talked about some of his experiences with node.js, his preference for using CoffeeScript rather than JS (despite it being harder to debug), many of the patterns he liked, some of the libraries he used and deployment matters. He was just as candid about some of the gotchas as well. A useful insight into the node.js system.</p>
<p>The last one of the day was <a href="http://funnel.hasgeek.com/jsfoo-pune/180-amplify-your-stack">Amplify your stack</a> by <a href="https://twitter.com/#!/threepointone">Sunil Pai</a>. He talked about a lot of libraries that could be used for client side development and deployment, about using javascript for templating, ensuring rigorous unit test coverage at all stages. Gave me the feeling there&#8217;s a lot I simply do not know about whats happening on the client side JS related libraries and frameworks. Couple of remarks I recollect &#8211; &#8220;You (the JS developer) own the browser&#8221; and &#8220;When you have a strong test case coverage, you can CODE BOLDLY&#8221;. </p>
<p><strong>Summary: </strong> There&#8217;s a lot I need to learn about whats happening on the client side. Thats true about the server side as well. And the day helped me understand just a little bit better what I don&#8217;t know. Yet I got the distinct feeling of discomfort with node.js. Not with the tool. But with the assumptions that seem to go with its usage. There was poor articulation about what kind of use cases it is good for. Except that it is really good for high thruput/no. of client connections. Either there was a misplaced understanding of it being the only good way to get this kind of thruput or there was inability to clearly articulate what other benefits developers could expect out of using node.js in situations where thruput/concurrent connections is not particularly important for them. Perhaps I was just at the wrong places when someone was offering a more insightful articulation of this. But I really did not hear it. </p>
<p>On the whole, I enjoyed the sessions, and this was a day very well spent. Hats off to <a href="https://twitter.com/#!/jackerhack">Kiran</a> and his team for organising a good event. Makes me look forward to the next one they organise.</p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2011/07/why-you-should-register-to-attend-python-conference-pune-sept-2011-right-now/' rel='bookmark' title='Permanent Link: Why you should register to attend Python Conference Pune (Sept 2011) right now'>Why you should register to attend Python Conference Pune (Sept 2011) right now</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1KFZ41RXF30:hsAcqs1xDis:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1KFZ41RXF30:hsAcqs1xDis:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=1KFZ41RXF30:hsAcqs1xDis:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1KFZ41RXF30:hsAcqs1xDis:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=1KFZ41RXF30:hsAcqs1xDis:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1KFZ41RXF30:hsAcqs1xDis:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/1KFZ41RXF30" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2012/01/conference-report-hasgeek-jsfoo-pune-2012/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2012/01/conference-report-hasgeek-jsfoo-pune-2012/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=conference-report-hasgeek-jsfoo-pune-2012</feedburner:origLink></item>
		<item>
		<title>Scala needs terraces</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/fOEdjKY6jx0/</link>
		<comments>http://blog.dhananjaynene.com/2012/01/scala-needs-terraces/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 23:52:42 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[functional programming]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[Uncategorized]]></category>

	<!-- AutoMeta Start -->
	<category>terraces</category>
	<category>flag</category>
	<category>terraces</category>
	<category>flag</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1209</guid>
		<description><![CDATA[Terrace (noun) : each of a series of flat areas made on a slope, used for cultivation, or a flight of wide, shallow steps providing standing room for spectators in a stadium Recently there was a useful discussion triggered off by the post True Scala complexity by Yang Zhang. Much has been debated about it [...]]]></description>
			<content:encoded><![CDATA[<p><em>Terrace (noun) : each of a series of flat areas made on a slope, used for cultivation, or a flight of wide, shallow steps providing standing room for spectators in a stadium</em></p>
<p>Recently there was a useful discussion triggered off by the post <a href="http://yz.mit.edu/wp/true-scala-complexity/">True Scala complexity</a> by <a href="https://twitter.com/#!/yaaang">Yang Zhang</a>. Much has been debated about it in the comments on the post and <a href="http://news.ycombinator.com/item?id=3443436">other forums</a>, most of it both articulate and constructive.</p>
<p>Martin Odersky proposed an idea on the ycombinator news thread as follows (next paragraph)</p>
<blockquote><p>So, I believe here is what we need do: Truly advanced, and dangerously powerful, features such as implicit conversions and higher-kinded types will in the future be enabled only under a special compiler flag. The flag will come with documentation that if you enable it, you take the responsibility. Even with the flag disabled, Scala will be a more powerful language than any of the alternatives I can think of. And enabling the flag to do advanced stuff is in any case much easier than hacking your own compiler.</p></blockquote>
<p>The basis of the idea wasn&#8217;t new. Martin himself had earlier suggested <a href="http://www.scala-lang.org/node/8610">Scala Levels</a>, though the suggested enforcement of two levels via a compiler flag was. While I thought it was a useful idea, strangely enough I found many (especially in the twitter streams I follow) less than enthusiastic. I think there exists a perspective where one can look at this idea with more enthusiasm, and this post details that.</p>
<p>Learning scala is non trivial. For a person who is well versed with Java programming and with little else, this will require learning at least the following (I am listing only a few items)</p>
<ul>
<li>Learning traits and objects (and unlearning statics). There&#8217;s a lot of stuff here including multiple inheritance, member overriding, whether the members should be defs or vals etc. which takes some times to get used to.</li>
<li>Learning to deal with immutability and occasionally lazy evaluation</li>
<li>Learning collections constructs such as for comprehensions or, map, flatMap, filter etc.</li>
<li>Understanding the capabilities that scala offers in terms of generics including being able to define co/contravariant collections, and then learning to use these capabilities effectively</li>
<li>Being able to understand and leverage many aspects of type theory</li>
</ul>
<p>Typically when a person makes a sustained effort driven by passion, he can cover a lot of ground very quickly. Thus some might be able to deal with the scala learning curve quickly. While this ability to learn could be achievable for many especially smaller companies, it is likely to be quite difficult for many others. Especially when the team sizes are large and/or developer capabilities might be modest, this is a real issue. One could form an analogy with a Cheetah and an Elephant. Some animals will be able to run fast individually, and others will trod slowly as a herd. One could wish elephants could run as fast as cheetahs but thats unhelpful, since the jungle is defined, and one best deal with it the way one finds it.</p>
<p>An ideal way to introduce scala would be to start with small groups of 3-5. But thats not practical in all cases. Besides for large teams, that means, most will need to wait for a much longer time before being able to use scala and profit from its substantial benefits. So lets say an organisation attempts to introduce scala in a modest team of say 20. Of which 2 are passionate, self driven souls, who tend to work much harder the rest to be able to progress much faster. Because learning to use scala the way scala wished to be used, is not a sprint but is a marathon (or at least a long distance jog), this creates issues. Soon enough the 2 are likely to run far ahead of the rest of the team and will start writing code which the others can&#8217;t grok. Even as some of the remaining may actually be struggling hard but are likely to be losing enthusiasm simply because they can&#8217;t find themselves being able to keep pace. An even bigger risk is the 2 continuing to make rapid progress even as they realise so much more remains to be learnt, even as the remainder are unable to start leveraging scala, since they still think there&#8217;s a lot of distance yet to cover and they become far more focused on catching up rather than leveraging what they have learnt. So while learning proceeds, actual development with direct economic benefit stalls. </p>
<p>Lets say hypothetically this team decided that they would only focus on reducing java boiler plate (which is a big deal) and continue to use scala in a primarily OO paradigm (since that is what they are used to) and defer learning remainder of scala by at least six months. There&#8217;s likely tons of benefits to be had by shifting to scala even with this limited scope. Yet all it takes to destroy harmony is one very enthusiastic developer. Who starts inserting (as yet) alien notions such as writing highly functional code, or implementing advanced type theory concepts (eg. scalaz) or starting to use a largely un-understood symbol soup (<a href="http://www.cakesolutions.net/teamblogs/2011/11/19/u-s-scalaz-layout/">scalaz</a> or the dispatch <a href="http://www.flotsam.nl/dispatch-periodic-table.html">periodic table</a>). This would make a mockery of the phased learning and force every one else to catch up (even if just to be able to read and maintain somebody else&#8217;s code).</p>
<p>We&#8217;ve long known hills are not conducive to agriculture. If these hills are our learning curves, fields could be considered to be directly impactful deployment of our skills. Agriculture generally happens flatlands and plateaus but not hillslopes. And yet we&#8217;ve learnt to tame the tall hills using terraces. Instead of climbing for a long time, climb a little &#038; grow a little. If teams can learn for a month, and deploy these skills for the next 6-9 months with the cycle repeating itself, it could help in the following ways :</p>
<ul>
<li>Organisations do not need to invest in long training times where the opportunity cost of lost development time is one large fixed cost.</li>
<li>Intra team disparity is likely to be contained since the deployment period will allow many to catch up with those in the lead</li>
<li>Instead of scala being viewed as one big leap, it could be viewed as a incremental leaps with managed effort. I saw a remark which said people anyways deal with complexity &#8211; its called OO. And Java programmers deal with OO. So they should be able to come to terms with scala quickly. But there is a difference. Java wasn&#8217;t as big a learning curve leap over C++ as Scala is over Java. And as importantly, a learning curve one has triumphed over already, somehow seems far less onerous than an identically sized one, one still needs to deal with.</li>
</ul>
<p>In short learning scala needs terraces. Terraces, where some developers will not run far ahead of the pack during the learning stages. Terraces where developers won&#8217;t have to feel too scared of alien&#8217;ish code suddenly appearing on their monitors. Terraces where developers will learn a few things and then deploy these skills over the next few months. These terraces could be made to work in different ways. It could just be a honour system using a set of levels identical or similar to the levels Martin Odersky proposed (though it would be extremely hard to ensure the same without tooling support). Or they could implemented using (as yet unwritten) tool like a scala-lint which will flag off advanced usages as warnings. Or as compiler switches the way Martin proposed. </p>
<p>There could be other ways to look at it too. Scala could be considered as a sharp weapon. Lethal in the hands of the trained. Self damaging in the hands of the untrained. So compiler switches could simply be a way to graduate from using sticks, to wooden swords, to blunt steel swords to the really sharp ones.</p>
<p>I saw a remark which said a compiler switch would divide the programmers. I seem to think such steps which help create terraces will divide the learning challenges. I also saw another remark which said, implementing compiler switches would play into the hands of languages like Kotlin or Ceylon or Fantom. I believe exactly to the contrary. The lower terraces can compete with Kotlin or Ceylon, and the upper terraces can provide a growth path that many other languages will not have. Not being able to plan a phased and an economically practical learning curve for large teams will make the case for other languages stronger. </p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2011/05/why-java-folks-should-look-forward-to-scala/' rel='bookmark' title='Permanent Link: Why Java folks should look forward to Scala'>Why Java folks should look forward to Scala</a></li>
<li><a href='http://blog.dhananjaynene.com/2011/08/cperformance-comparison-languages-styles-and-vms-java-scala-python-erlang-clojure-ruby-groovy-javascript/' rel='bookmark' title='Permanent Link: Contrasting Performance : Languages, styles and VMs &#8211; Java, Scala, Python, Erlang, Clojure, Ruby, Groovy, Javascript'>Contrasting Performance : Languages, styles and VMs &#8211; Java, Scala, Python, Erlang, Clojure, Ruby, Groovy, Javascript</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=fOEdjKY6jx0:MVzj3IpQjJk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=fOEdjKY6jx0:MVzj3IpQjJk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=fOEdjKY6jx0:MVzj3IpQjJk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=fOEdjKY6jx0:MVzj3IpQjJk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=fOEdjKY6jx0:MVzj3IpQjJk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=fOEdjKY6jx0:MVzj3IpQjJk:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/fOEdjKY6jx0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2012/01/scala-needs-terraces/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2012/01/scala-needs-terraces/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=scala-needs-terraces</feedburner:origLink></item>
		<item>
		<title>Which risk would you manage? What would you want to prove? Programming Languages and Type Systems</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/mf7fMVBA6_Q/</link>
		<comments>http://blog.dhananjaynene.com/2011/10/which-risk-would-you-manage-what-would-you-want-to-prove-programming-languages-and-type-systems/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 21:45:32 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>

	<!-- AutoMeta Start -->
	<category>provability</category>
	<category>iterate</category>
	<category>inputs</category>
	<category>backwards</category>
	<category>risks</category>
	<category>meeting</category>
	<category>provability</category>
	<category>iterate</category>
	<category>inputs</category>
	<category>backwards</category>
	<category>risks</category>
	<category>meeting</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1202</guid>
		<description><![CDATA[Debates across programming languages and type systems are not new. And this post does not attempt to shed new light on these (though it is hardly an un-opinionated view) Yet one point that keeps on bothering me time and again. That the lens used to visualise the many issues around these help clarify, magnify but [...]]]></description>
			<content:encoded><![CDATA[<p>Debates across programming languages and type systems are not new. And this post does not attempt to shed new light on these (though it is hardly an un-opinionated view) </p>
<p>Yet one point that keeps on bothering me time and again. That the lens used to visualise the many issues around these help clarify, magnify but lose the bigger picture. This post suggests a broader view to be applied. </p>
<p>Every argument refers to either improved benefits, lower costs or better contained risks. And in fact much of the arguments focusing proving the correctness of the code, or compiler ensured verification and thus the resultant guarantees, or the extent of unit test required to cover a wide array of differently typed inputs all boil down to risk. </p>
<p>The risk of code not behaving precisely like the way the author intended it to behave. </p>
<p>Yet there are other risks. </p>
<p>* The risk of spending too much time building something you eventually realise is either not required.<br />
* The risk of not being able to provide rapid feedback to the product team, OR The risk of the customer not being able to partake and participate in your newest features to provide you critical inputs<br />
* The risk of building a fantastic software, but a software that in hindsight needed to be very different.</p>
<p>When rewriting a legacy system, you often know exactly how you would like things to be rebuilt. When having adequate cash flows from alternate revenue streams, which can absorb product development costs, the life of your company may not depend upon the particular development in progress. When a part of a very large enterprise where anyways tons of internecine political empires rule the roost, a particular product / project development may hardly influence overall corporate risk. </p>
<p>In each of these situations &#8211; the risk of the software being developed is largely the same as the risk of the software getting delivered. Thats when risk is measured in terms of the software not meeting its feature, performance or delivery schedule goals. Thats when risk management becomes very important. Thats when provability, robustness etc. become important metrics for predictively containing risk. </p>
<p>Yet, not all environments have that luxury. Startups especially. Those that are dependent strongly on a piece of software &#8211; bet the farm on that software. Many actually have only a blur of an idea &#8211; but require tremendous market feedback to refine the vision. Yet others are operating on fixed constraints in terms of budgets before they decide whether the investments they made are worthy of further investments or whether to cut the losses. The risks here are very different. </p>
<p>In such situations &#8211; the risk to manage is not the risk of software correctly meeting its specifications. Its the risk of the software specifications not correctly meeting the market expectations. The real risk here is agility. Can you create the minimal functionality needed for feedback in the quickest manner. Can you act on the received feedback to adapt in the most competitive manner. In short can you iterate. Again. And again. And again. Fast enough before the market throws you out, or your competitor eats your lunch or your budget runs out. Work backwards from these goals. And you&#8217;ll find the right type system. And programming language. For you. </p>
<p>Programming languages and type systems are but vehicles to goals. Work backwards from your customer satisfaction perspective, your particular organisational constraints (or lack of them), your imperatives to iterate, and your time to market pressures. Work backwards from these to understand what exactly your company&#8217;s life depends upon. And of course factor in your current strengths (languages known / experience levels etc.). The right type systems and programming language should be relatively easy to decide. </p>
<p>And yes, provability is important. So long as you know exactly what you wish to prove first. The software or your business model.</p>
<p>Oh, lest you feel confused which type systems I prefer, I am ambivalent. They exist because they all have a role to play. But I do believe each context has one right choice. Just make the right choice for your context. And yes the programming languages I program in currently are Python and Scala. And yes, I have found in my experience dynamically typed languages help very substantially when fast TTM or iteratibility is needed (a view not everyone shares)</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=mf7fMVBA6_Q:HBXZmwZOnZM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=mf7fMVBA6_Q:HBXZmwZOnZM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=mf7fMVBA6_Q:HBXZmwZOnZM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=mf7fMVBA6_Q:HBXZmwZOnZM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=mf7fMVBA6_Q:HBXZmwZOnZM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=mf7fMVBA6_Q:HBXZmwZOnZM:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/mf7fMVBA6_Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2011/10/which-risk-would-you-manage-what-would-you-want-to-prove-programming-languages-and-type-systems/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2011/10/which-risk-would-you-manage-what-would-you-want-to-prove-programming-languages-and-type-systems/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=which-risk-would-you-manage-what-would-you-want-to-prove-programming-languages-and-type-systems</feedburner:origLink></item>
		<item>
		<title>Contrasting Performance : Languages, styles and VMs – Java, Scala, Python, Erlang, Clojure, Ruby, Groovy, Javascript</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/d2sNbk2fZtg/</link>
		<comments>http://blog.dhananjaynene.com/2011/08/cperformance-comparison-languages-styles-and-vms-java-scala-python-erlang-clojure-ruby-groovy-javascript/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 14:12:34 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[functional programming]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[comparison]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[pypy]]></category>
		<category><![CDATA[v8]]></category>

	<!-- AutoMeta Start -->
	<category />
	<category />
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1144</guid>
		<description><![CDATA[Major update This blog post is now formally retracted. A part of the original post remains. As does a record of the contributors and a log of the annotations of the updates. The code also remains on github. What are deleted are the actual published results, and some other sections that are now less relevant [...]]]></description>
			<content:encoded><![CDATA[<p><strong><i>Major update</i></strong></p>
<p>This blog post is now formally retracted. A part of the original post remains. As does a record of the contributors and a log of the annotations of the updates. The code also remains on github. What are deleted are the actual published results, and some other sections that are now less relevant after this retraction. Added is the narrative about the reason for retraction. </p>
<p>The way this post started was a casual exercise in measuring performance of my earlier python code in pypy. I found the results interesting, so soon tried the same in Erlang. Having found the same to be interesting as well, very soon I found myself adding more languages and different coding styles resulting into a set of exercises which caused me to think (naively in hindsight) &#8211; hmmm, these results do tell me something. And probably the learnings are useful enough to share. It disappoints me to not be able to continue to share the same. Yet thats what I am just doing.</p>
<p><i>Why ?</i></p>
<ul>
<li>Insufficient detailing of constraints : As Isaac points out in the comments <a href="http://blog.dhananjaynene.com/2011/08/cperformance-comparison-languages-styles-and-vms-java-scala-python-erlang-clojure-ruby-groovy-javascript/#comment-9433">here</a>, I had defined the set of constraints around the coding styles a little loosely. Once I had opened up the results and opened up the entire topic for a number of submissions &#8211; these started becoming an issue. As an example the early versions of the benchmarks used lists &#8211; yet some of the languages have have no exclusive lists, so one uses array like structures as well. These started a set of suggestions that one should use arrays instead of lists in other languages as well. That was just a starting point being cited as an example of how a lack of clear constraints started influencing the code. It also points out to the difference in rigour required between conducting exercises for self understanding and publishing the same.</li>
<li>Inability to keep code in other languages updated : It was rather painfully obvious to me that as some of the contributions were being implemented, the same were also candidates for leveraging in other languages. Yet the lack of time prevented me from being able to do so. Thus even as I was adding contributions to remain fair to each implementation, I was being unfair by not applying the underlying efficiencies leveraged by these contributions to other languages simultaneously.</li>
<li>Running out of time : I am likely to be extremely busy over the coming month. Yet there still were a number of contributions still coming in. Given the priorities I need to work upon, this blog post was not amongst the more important ones. Yet I imagined, if new submissions came in, I simply would no longer have time to deal with the same. Again resulting in a degree of unfairness that would not be acceptable to me.</li>
<li>Letter or Spirit : Performance Benchmarks need to be written to reflect the letter and the spirit of the language. I would&#8217;ve preferred to measure the performance implications using the features as advertised. There&#8217;s no point advertising a luxury car packed with a ton of features and a cost, and then simultaneously publishing speed results using a rally car version &#8211; which has a lot of the weight thrown out (and would actually cost a lot more than the commercial car to maintain). (The analogy fails partially, since in programming we can combine the two based on varying contexts). The judgement of the right spirit is extremely subjective. A decision I did not find myself (and perhaps most others given the subjectivity) capable of making fairly. And yet keeping benchmarks focused on the letter without the spirit was rather uninteresting for me (YMMV).</li>
</ul>
<p>I find myself a little wiser and a lot humbled. The learnings above are unlikely to be forgotten. I also find myself much more aware of the performance implications of code thats consistent with my subjective understanding of idiomatic. The original reason I started this exercise has satisfied its objective in terms of an improved personal understanding, perhaps even more so because of a number of contributions I received. Thats a useful learning as well. </p>
<p>The results that were published earlier on this page need to go. The code continues to remain on github for your perusal and further tweaking based on your definition of letter and spirit.</p>
<p>Sincere thanks to all who contributed. Particularly to Isaac. I learnt a lot from him. Further activity on this post shall cease.</p>
<p><strong><i>Parts of the Original Post</i></strong></p>
<p>There&#8217;s a better place to specifically look at performance comparisons across languages than this post &#8211; <a title="The computer languages benchmarks game" href="http://shootout.alioth.debian.org/">The computer languages benchmarks game</a>. But this post attempts look at performance comparisons a little differently. Based on coding idioms as well. And for a much narrower range of problems (namely one).</p>
<p>There are languages which are tightly opinionated on a particular way of doing things. And there are languages which allow you to implement a given logic in multiple ways. Yet, depending upon the language (and as we shall see, the runtime), the performance could vary quite substantially based on the nature of the code we write. This post attempts to take a small piece of logic, and implements in upto 3 different styles in 8 languages (10 if you count the runtime variations as well).</p>
<p>[..]</p>
<p><strong>Problem</strong></p>
<p>Quoting from <a title="The Josephus Problem" href="http://danvk.org/josephus.html">The Josephus Problem</a>,</p>
<p>Flavius Josephus was a roman historian of Jewish origin. During the Jewish-Roman wars of the first century AD, he was in a cave with fellow soldiers, 40 men in all, surrounded by enemy Roman troops. They decided to commit suicide by standing in a ring and counting off each third man. Each man so designated was to commit suicide…Josephus, not wanting to die, managed to place himself in the position of the last survivor.</p>
<p>In the general version of the problem, there are n soldiers numbered from 1 to n and each k-th soldier will be eliminated. The count starts from the first soldier. What is the number of the last survivor. In the code I benchmarked, n = 40 and k = 3.</p>
<p><i>Update. Note:</i> Some are getting confused that I start by striking out the very first soldier in the chain and then starting to count up to the k value. This is one of the variations of the Josephus problem I had introduced this time. All the versions implement this logic consistently.</p>
<p><strong>Idioms</strong></p>
<p>I have considered three idioms :</p>
<ul>
<li><strong>Object Oriented :</strong> This code has classes reflecting a person (or a soldier) and the chain. The objects of person maintain reference to their prior and next people in the cirlce (a doubly linked list, and as the counting progresses, whenever they need to eliminate themselves, they do so by updating the next / prev references in the prev / next objects. This style results perhaps in the least operations involving mutation or memory allocation / deallocation. One would&#8217;ve imagined it to be the fastest, but as you will see that is not necessarily true.</li>
<li><strong>List reduction :</strong>This code starts with a list of integers, each element representing a soldier. It performs an operation which effectively creates a subset of the list by removing every third soldier. The result of one such pass is a smaller list. Rinse and repeat if the smaller list is more than 1 element long. It emphasises looping over lists (using comprehension or other constructs) and focuses on reducing the list by conducting an operation on the entire list, every pass.</li>
<li><strong>Element recursion :</strong>This is a more fine grained logic which emphasises recursion (and often accumulation) for every element in the list. This is particularly apt scenario to use pattern matching (both the erlang and scala code use pattern matching). One would imagine this to be always slower than list reduction since it is much more fine grained and involves many more function calls.</li>
</ul>
<p>I&#8217;ve attempted to implement code in all languages using the styles above as long as reasonably feasible and appropriate. Since (barring C/C++), Java continues to be the language to beat from a performance perspective, I&#8217;ve attempted to implement roughly equivalent logic in all styles using Java as well. All programs typically run the code once to print the results (to verify correctness), and then 100000 or a million iterations to warmup, and then again repeat the iterations and measuring the elapsed time. There is a slight inconsistency between the various code snippets. The counter either varies between 0 to 39 or between 1 to 40. </p>
<p><strong>Contributions</strong></p>
<p>I can&#8217;t write the fastest possible code across all these languages. This is the best I could do. However if you can find a better way to implement the code, do let me know in the comments (or send me a pull request on github). I shall certainly include better solutions here if and as they are identified. At the point in time of publishing this, at least two authors had contributed to the code. I imagine (based on my experience with the prior post), more might be interested in suggesting tweaks to further improve performance. These are all listed here.</p>
<ul>
<li>Paddy3118 had suggested some python code in the comments in last blog post, which I have substantially reused for the python list-reduction logic</li>
<li><a href="http://twitter.com/#!/missingfaktor" title="Rahul Göma Phuloré (missingfaktor)">Rahul Göma Phuloré (missingfaktor)</a> contributed substantial improvments to the scala code</li>
<li><a href="http://twitter.com/#!/viktorklang">Viktor Klang</a> contributed a improved version for the scala element recursion code</li>
<li><a href="http://twitter.com/#!/swannodette">David Nolen (swannodette)</a> contributed a substantially improved version for clojure element recursion, and the java like versions for clojure</li>
<li><a href="http://twitter.com/#!/mononcqc">Fred Hebert</a> suggested native compilation by adding &#8220;compile(native).&#8221; and a couple of other minor improvements over github</li>
<li>Isaac Guoy offered an improved Java, Python and Javascript versions and code for an alternative oo + element-recursive style. The alternate style code is to be found in the contrib directory.</li>
<li><a href="http://twitter.com/#!/alextkachman">Alex Tkachman</a> offered code for use with Groovy++</li>
<li><a href="http://twitter.com/#!/stuarthalloway">Stuart Halloway</a> submitted clojure element-recursion implementation</li>
</ul>
<p><strong>Hardware / Software</strong></p>
<p>Removed</p>
<p><strong>Metrics :</strong></p>
<p>Removed</p>
<p><strong>Observations :</strong> <i>(Updated)</i></p>
<p>Removed.</p>
<p>Full Source code is available on github at <a href="https://github.com/dnene/josephus">https://github.com/dnene/josephus</a></p>
<p>Finally, thanks to a number of folks I had a chance to preview the post with and especially to Saager Mhatre to suggest moving the code from a attached zip file to github.</p>
<p><strong>Updates</strong></p>
<ul>
<li>Updated metrics for groovy 1.8.1 (instead of earlier groovy 1.7)</li>
<li>Updated code to reflect suggestions by Eric Rozendaal and another almost similar one by Viktor Klang &#8211; Viktor&#8217;s code was very marginally faster. Leads to a reduction in Scala Element Recursive benchmark</li>
<li>Updated clojure element recursion code as per suggestion by David Nolen. </li>
<li>Thanks to the persistent questioning by Isaac, upgraded the metrics to jRuby 1.6.3. That turned out to be a very good step. There is a substantial improvements in the performance metrics which are now updated in the numbers above.</li>
<li>Fred Hebert submitted a pull request to turn on native compilation which required native compilation &#8211; which in turn required HiPE which Isaac had suggested earlier. After verifying that Erlang-HiPE is a valid synaptic target (thus a different readily available VM), I built the same and updated the readings</li>
<li>Isaac Gouy offered some helpful suggestions in terms of converting the main block also into a function. Also he demonstrated some potential issues in terms of whether the resulting performance was stable. I have made across the board changes now to run all the benchmarks ten times each for a million iterations and used the last 5 readings after visually ensuring that the readings did not vary much</li>
<li>Isaac further suggested improvements to the Java List Reduction and Element Recursion techniques which have now been incorporated. He has also contributed a perhaps faster version of OO code, which is less consistent with the other OO code being benchmarked. Need to identify how best to factor that in. Perhaps a yet other contrib section in the source?</li>
<li>Added newer versions of Java and Javascript contributions from Isaac, and Clojure contributions from David Nolen. I have only recently seen some more alternative implementations for clojure, and have received a Groovy++ contribution .. both I&#8217;ll explore over the weekend</li>
<li>Updated Pypy results to Pypy 1.6 now that it has beeen released.</li>
<li>Added contribution by Stuart Halloway for clojure using LinkedList for element recursion </li>
<li>Added code contributed by Alex Tkatchman for Groovy++. This I would remark has exceedingly good performance. You can find it in the contrib section.</li>
<li>Added further code contributions by Isaac for Python.</li>
</ul>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2011/05/why-java-folks-should-look-forward-to-scala/' rel='bookmark' title='Permanent Link: Why Java folks should look forward to Scala'>Why Java folks should look forward to Scala</a></li>
<li><a href='http://blog.dhananjaynene.com/2011/07/why-you-should-register-to-attend-python-conference-pune-sept-2011-right-now/' rel='bookmark' title='Permanent Link: Why you should register to attend Python Conference Pune (Sept 2011) right now'>Why you should register to attend Python Conference Pune (Sept 2011) right now</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=d2sNbk2fZtg:a71GGCWnYVA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=d2sNbk2fZtg:a71GGCWnYVA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=d2sNbk2fZtg:a71GGCWnYVA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=d2sNbk2fZtg:a71GGCWnYVA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=d2sNbk2fZtg:a71GGCWnYVA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=d2sNbk2fZtg:a71GGCWnYVA:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/d2sNbk2fZtg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2011/08/cperformance-comparison-languages-styles-and-vms-java-scala-python-erlang-clojure-ruby-groovy-javascript/feed/</wfw:commentRss>
		<slash:comments>70</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2011/08/cperformance-comparison-languages-styles-and-vms-java-scala-python-erlang-clojure-ruby-groovy-javascript/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=cperformance-comparison-languages-styles-and-vms-java-scala-python-erlang-clojure-ruby-groovy-javascript</feedburner:origLink></item>
		<item>
		<title>Why you should register to attend Python Conference Pune (Sept 2011) right now</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/b8s5cgFEHnc/</link>
		<comments>http://blog.dhananjaynene.com/2011/07/why-you-should-register-to-attend-python-conference-pune-sept-2011-right-now/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 09:44:42 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[pycon]]></category>
		<category><![CDATA[pycon india]]></category>

	<!-- AutoMeta Start -->
	<category>pycon</category>
	<category>2011</category>
	<category>pune</category>
	<category>register</category>
	<category>punetech</category>
	<category>biggest</category>
	<category>navin</category>
	<category>conference</category>
	<category>pycon</category>
	<category>2011</category>
	<category>pune</category>
	<category>register</category>
	<category>punetech</category>
	<category>biggest</category>
	<category>navin</category>
	<category>conference</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1127</guid>
		<description><![CDATA[This is a guest / cross post from original one as appeared on PuneTech written by Navin Kabra. Thank you Navin, for the permission to reproduce the same. Disclaimer : Both I and Navin are on the organising team of PyCon India 2011. However we act in a volunteer capacity to help further encourage python [...]]]></description>
			<content:encoded><![CDATA[<p><i>This is a guest / cross post from <a href="http://punetech.com/why-you-should-register-to-attend-python-conference-pune-sept-2011-right-now/">original one</a> as appeared on <a href="http://punetech.com">PuneTech</a> written by <a href="http://punetech.com/navin/">Navin Kabra</a>. Thank you Navin, for the permission to reproduce the same.</i></p>
<p><i>Disclaimer : Both I and Navin are on the organising team of PyCon India 2011. However we act in a volunteer capacity to help further encourage python and software development activities. We do not gain financially from this association. PuneTech is a blog specifically focused on encouraging technology developments in Pune.</i></p>
<p/>
<p><a href="http://in.pycon.org">PyCon India</a>, the International Python Conference that happens in India every year, will be in <a href="http://in.pycon.org/2011">Pune</a> this year on September 16-18, 2011</a>. <a href="http://in.pycon.org/2011/register">Early Bird Registration &#8211; Rs. 300 (includes lunch, 3 days)</a> is open until the end of the week. <a href="http://in.pycon.org/2011/register">Register now!</a> If you need convincing as to why you should attend Pycon, here are some reasons:</p>
<ul>
<li><strong>Raymond Hettinger</strong>, one of the top pythonistas in the world is the keynote speaker. <a href="http://us.pycon.org/2011/speaker/profile/131/">Raymond</a> (<a href="http://twitter.com/raymondh">@raymondh</a> on twitter) is a Python core developer. He is the author of the <i>itertools</i> and <i>set</i> modules and most of the <i>collections</i> modules in the standard library, the peephole optimizer for Python, and dozens of ASPN cookbook recipes. It will literally be many years before you get a chance to hear a technologist of this calibre.</li>
<li><strong>Learn Python:</strong> This is your chance to learn Python. Start learning Python right now, and by September, you&#8217;ll be ready to get maximum value out of the tutorials in the conference (including Twitter/Facebook/Linked-in/Google Data hacking, web scraping, image processing, and functional programming using Python). If you need arguments on why everybody must learn python check <a href="http://punetech.com/improve-your-web-based-software-development-and-maintenance-roi-with-dynamic-programming-languages/">here</a>, <a href="http://punetech.com/why-python-is-better-than-java/">here</a> and <a href="http://reliscore.com/why-every-programmer-should-learn-python-or-ruby">here</a>.</li>
<li><strong>Excellent Talks:</strong> There are <a href="http://in.pycon.org/2011/talks">24 high quality talks</a>, on all kinds of interesting topics including Data Analysis and Business Intelligence, Python-to-Javascript cross-compliation, Telephony apps, Robotics, Web Apps, Python in Biology and Life-Sciences, Cloud Computing, Android, testing, GIS, and much more. There is also one talk on using Python to do your homework.</li>
<li><strong>Meet Smart People:</strong> Even if you don&#8217;t agree that people who choose to work with Python are smarter than most others, you will have to agree that this will be one pretty darn interesting bunch of 500+ developers from all over India and outside. Rs. 300 to get a chance for that kind of networking is nothing.</li>
<li><strong>Hire Smart People:</strong> If you are having trouble hiring top quality technology talent for your company, you definitely need to be at PyCon, handing out your card, and telling everybody what a cool company you work for. Far better use of your time than going through resumes sent to you by your recruiter.</li>
<li><strong>Just Rs. 300:</strong> <a href="http://in.pycon.org/2011/register">Early Bird Registration</a> closes on 1st August, so act now. That&#8217;s only Rs. 300 for a high quality conference and it includes lunch and snacks for the 3 days of the conference. That&#8217;s right, you&#8217;ll be paying less than the cost of the food! And, unlike the other, regular tech events that happen in Pune, this is not a cheapo event &#8211; there will be swag &#8211; T-shirts and other stuff being given away. Did you realize that PyCon sponsors are paying for the privilege of giving you free stuff?</li>
<li><strong>Make PyCon Pune the biggest PyCon:</strong> Pune now has a reputation to keep up &#8211; whenever any tech event that happens in different cities, invariably, the biggest turn-out is for the Pune instance. <a href="http://punetech.com/phpcamp-the-biggest-php-conference-in-india-in-pune-on-5th-march/">PHPCamp</a> with 1000+ registrations and 700+ actual attendance is probably the biggest ever tech unconference/barcamp style event in the country. <a href="http://punetech.com/doctype-html5-free-1-day-conference-on-html5css-in-pune-dec-4/">DocType HTML5 in Pune</a> had far more registrations than other places and the organizers had to close registrations. Recently <a href="http://onlygizmos.com/gizmomeet-5-pune-photos-videos/2011/07/">GizmoMeet had their biggest turnout in Pune</a>. The Python community in Pune is far younger than the Python community in Bangalore, so it will be tough for Pune PyCon to beat the Bangalore PyCon, but we definitely need to give them a at least a tough fight.</li>
</ul>
<p>What are you waiting for? <a href="http://in.pycon.org/2011/register">Register now</a></p>
<p><em>(We&#8217;d like to mention here that amongst the various sponsors of PyCon (including Google and GitHub), are these cool Pune companies/institutions: Venue sponsor: <a href="http://symbiosis.ac.in/">Symbiosis</a>, Gold: <a href="http://vayana.in">Vayana</a>, Silver: <a href="http://druva.com">Druva</a> and <a href="http://gslab.com">GSLab</a>)</em></p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=b8s5cgFEHnc:gPY_1cc6dGo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=b8s5cgFEHnc:gPY_1cc6dGo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=b8s5cgFEHnc:gPY_1cc6dGo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=b8s5cgFEHnc:gPY_1cc6dGo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=b8s5cgFEHnc:gPY_1cc6dGo:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=b8s5cgFEHnc:gPY_1cc6dGo:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/b8s5cgFEHnc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2011/07/why-you-should-register-to-attend-python-conference-pune-sept-2011-right-now/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2011/07/why-you-should-register-to-attend-python-conference-pune-sept-2011-right-now/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=why-you-should-register-to-attend-python-conference-pune-sept-2011-right-now</feedburner:origLink></item>
		<item>
		<title>Google Plus : Getting close to the sweet spot by getting the basics right</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/GOna-_eHoI4/</link>
		<comments>http://blog.dhananjaynene.com/2011/07/google-plus-getting-close-to-the-sweet-spot-by-getting-the-basics-right/#comments</comments>
		<pubDate>Sat, 09 Jul 2011 23:44:36 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[Internet and Social Media]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[google plus]]></category>
		<category><![CDATA[twitter]]></category>

	<!-- AutoMeta Start -->
	<category />
	<category />
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1110</guid>
		<description><![CDATA[My first reaction to google plus was Nice. But facebook has a lockin on the friends and people will not shift until their friends shift which will pretty much mean most will play around with google and then go back to facebook since thats where their friends are. As I played with it a little [...]]]></description>
			<content:encoded><![CDATA[<p>My first reaction to google plus was <em>Nice. But facebook has a lockin on the friends and people will not shift until their friends shift which will pretty much mean most will play around with google and then go back to facebook since thats where their friends are.</em></p>
<p>As I played with it a little more, I realised the Circles were a little confusing. It took me a while to realise who exactly got to see my posts when I posted them to my extended circle. While they allowed you a more natural way to constrain publishing to a private subgroup of your network, their organisation wasn&#8217;t exactly simple or natural (though I&#8217;m sure Google worked very hard even to get circle management to its current shape). Despite its bold move on circles that has been well received. I think circles will need to be better managed. It will perhaps take some time for the feedback from the community to find its way back into superior circle management. </p>
<p>So while I was willing to give it more credit than google wave, it didn&#8217;t quite blow me off my feet. And I imagined facebook to continue to be the unchallenged king of social networking. </p>
<p>As I used it over the week, I felt my perceptions changing. Not in a manner that I could feel the change strongly, but slowly and quietly. And then it struck me. The gauntlet had indeed been thrown quite credibly. And the king is now being challenged.</p>
<p>Here&#8217;s why. At a very fundamental level, google is changing the game. And it is not wanting to be the king of the social networks as understood today. It wants to be the be king of social networks that will be. </p>
<p><strong>The Public / Private Asymmetric Network</strong> :</p>
<p>Facebook is a private network. Sure you can make your facebook status update completely visible for everyone to see, but thats really an atypical usecase. Facebook allows me to bring online the <em>friends I made in the past</em>. Friends I now therefore trust. Friends I can make remarks to that I wouldn&#8217;t want to make publicly. And barring a few exceptions (eg. when someone ranted about their job only to find their boss reading the rant), the model held. Privacy is important, critical <em>and</em> assumed. Any real or perceived violations of privacy are met with an uproar. What facebook does not allow me to do (at least based on the easily understood controls available to me) is create further subgroups within my network (it actually does that &#8211; but I rarely find myself using these features and doubt if many others use them). It takes my &#8220;offline photosharing&#8221; and makes it &#8220;online&#8221;. It takes my &#8220;offline gossip&#8221; and makes it &#8220;online&#8221;. Facebook &#8220;takes my offline network&#8221; and &#8220;makes it online&#8221;.</p>
<p>Twitter on the other hand is a public network. There should be a tagline which says &#8220;Everything you say, can and do will be used against you in a court of law, in your classroom, in your job, in your sports team and even within your friends and family&#8221;. But its not really required, and no one misses it, since most Twitter users very quickly understand it. With twitter, I can eavesdrop on conversations between two other twitter users, and neither of them are likely to object nor am I likely to feel guilty &#8211; since that is consistent with the conventional protocol. Twitter is a public network. It is perfectly normal for strangers to start engaging in a conversation. It therefore has this end result called &#8220;serendipitous discovery&#8221; of both information and relationships. Most of the people I interact with on twitter are people I met online. And later on I feel nice when I end up meeting them in real life. Twitter is all about &#8220;discovering an online network&#8221; and then when feasible &#8220;bringing part of the online network offline&#8221;. </p>
<p>Twitter is also an asymmetric network. While facebook carries friendships online, twitter enabled followings in an asymmetric fashion. Which allows me to fine tune the messages that I choose to listen to. Thus I am no longer required to read the status updates of those who wish to read mine. (Facebook allows this too via hiding- but again thats probably not a very typical behaviour). Offline conversations are constrained by space and time &#8211; the people who are conversing need to be at the same place at the same time. Thus they are often necessarily symmetrical (An example where that is not true is when a charismatic leader is say addressing a large crowd &#8211; the leader hardly knows each person in the crowd, though they all know him a lot better). Online networking removes the constraints of space and time. Thus asymmetric relationships are much easier to support.</p>
<p>While most understood facebook very quickly, for a lot of people the response to Twitter is &#8220;I don&#8217;t get it&#8221;. And part of the reason is that twitter does not convert an offline network to online network, but is really pushing at the boundaries of <em>what an online network can be</em>. While I value the privacy of my data on facebook, I actually value the serendipitous discovery and the astonishing learning I can benefit from with twitter so much more, because it has enabled communication and network patterns that were not earlier feasible in offline networks given constraints of space and time. And while the 140 character magic holds, it does become painful when tracking long and convoluted conversations. </p>
<p>Google Plus groks this. It has smartly enabled the capabilities and features of a public and private network. While you can push your posts on the public channel and eavesdrop and participate on conversations others are holding on the public channel, it simultaneously affords you the choice to constrain your messages to the specific group of people that you would choose to constrain them to. It also has the most rudimentary capabilities to start building an interest graph. And it is asymmetric which helps each person maximise the value he gets from the network. Moreover it has features to allow me to implement the appropriate communication patterns with people that I share my childhood photographs with, with those I work with, and those that inspire me. It has simultaneously enabled private gossipy conversation, listening into the people I respect (not befriend), and serendipitous discovery. </p>
<p>Ka Ching!</p>
<p><strong>The unified consolidated channel</strong></p>
<p>Once upon a time, I had a watch, a camera, a phone, an alarm clock, a map, a hi-fi audio system, a radio, a TV / DVD player to play my DVDs. Now I have a smart-phone. And while the really keen will continue to own each or some of the individual components, it is neither a surprise nor a secret, that my smartphone is ever encroaching into their territories. We want these together, and we want them to be easy to carry.</p>
<p>While online services are inherently portable and thus the physical form factor of having to carry them around is not applicable, the integration of various service is an important factor. Google Plus is but one element of a broader channel. Incoming notifications on google plus show up in a small red box at the top right corner of my gmail tab. Now imagine gmail, google docs, google plus, picasa, youtube, google maps, google music, google latitude, google storage all getting (social / interest) network enabled. And imagine them being available in google apps also. And imagine them simultaneously available on desktops, netbooks, notebooks, tablets and mobile phones. Google already has most of these pieces &#8211; what it lacked is that these were not &#8220;network friendly&#8221;. Imagine each of these assets becoming network friendly &#8211; I can publish google docs to a specific circle I had defined on google plus. It has been suggested that the google plus we see today is but an early stage view of what is likely to be a continuous rollout of features over a year. Whether you look at facebook, linkedin, slideshare, foursquare, skype, or quora &#8211; they are the watch makers, camera makers, radio makers. Google is building the online smartphone. And that will probably be the important advantage google will have to offset facebook&#8217;s entrenched user base. That will cause many of your friends on Facebook to also start using Google Plus. Google Plus is google&#8217;s one ring to bind them all. </p>
<p><strong>Openness</strong> :</p>
<p>Facebook did a phenomenal job in opening up its screen real estate to a number of other applications through its platform API. However it has also attempted to lock-in the users by licensing constraints. (eg. <a href="http://scobleizer.com/2008/01/03/ive-been-kicked-off-of-facebook/">Robert Scoble getting his facebook account disabled</a>). On the other hand google has made a <a href="http://www.dataliberation.org/">public commitment</a> to keep its data under the users&#8217;s control all the time including being able to move it out. As we start utilising the graphs we build across many more applications, and especially the more serious ones than the FarmVilles at Facebook, data openness will continue to become more critical. Unless others play catch up with google, in terms of its commitment to open data &#8211; this will start becoming an increasingly stronger factor in google&#8217;s favour.</p>
<p><strong>In summary</strong></p>
<p>Google plus is credible execution to fill an important gap in google&#8217;s earlier offerings. However it goes well and beyond just private social networking. It is really building public / private, asymmetric networking built using social graphs based on friendships, work relationships, online discoveries and probably soon enough interest graphs as well. It is building the network that will be. While google wants to own the experience, it is liberal enough to publicly commit that the data is owned by the user. Combined with the awesome google portfolio and its evergrowing warchest built out of search advertising revenues &#8211; This is the network to beat.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=GOna-_eHoI4:Q5N2l8r5zWM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=GOna-_eHoI4:Q5N2l8r5zWM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=GOna-_eHoI4:Q5N2l8r5zWM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=GOna-_eHoI4:Q5N2l8r5zWM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=GOna-_eHoI4:Q5N2l8r5zWM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=GOna-_eHoI4:Q5N2l8r5zWM:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/GOna-_eHoI4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2011/07/google-plus-getting-close-to-the-sweet-spot-by-getting-the-basics-right/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2011/07/google-plus-getting-close-to-the-sweet-spot-by-getting-the-basics-right/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=google-plus-getting-close-to-the-sweet-spot-by-getting-the-basics-right</feedburner:origLink></item>
		<item>
		<title>Why Java folks should look forward to Scala</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/g7A3g_9b5gs/</link>
		<comments>http://blog.dhananjaynene.com/2011/05/why-java-folks-should-look-forward-to-scala/#comments</comments>
		<pubDate>Mon, 30 May 2011 23:46:42 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[functional programming]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[C#]]></category>

	<!-- AutoMeta Start -->
	<category />
	<category />
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1091</guid>
		<description><![CDATA[There&#8217;s an interesting series of blog posts in progress: Why Java folks should stop looking down on C# : Part 1 and Part 2 (at the point of time of writing this post). It offers an interesting and detailed set of contrasts between Java and C#. It is a detailed analysis and makes for very [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s an interesting series of blog posts in progress: Why Java folks should stop looking down on C# : <a href="http://blog.kalistick.com/java/why-java-folks-should-stop-looking-down-on-c-differences-in-similarities/">Part 1</a> and <a href="http://blog.kalistick.com/java/why-java-folks-should-stop-looking-down-on-csharp-a-brand-new-world/">Part 2</a> (at the point of time of writing this post). It offers an interesting and detailed set of contrasts between Java and C#. It is a detailed analysis and makes for very worthwhile reading. What really intrigued me was this comment :</p>
<blockquote><p><em>&#8220;We notice that Java developers generally tend to look scornfully at C#, as a copycat created by Microsoft and used by dummies. In theses blog series, I am going to try to sweep this nonsense and show some of the C# goodness.&#8221;</em></p></blockquote>
<p>At least in my experience, I do not recollect Java developers looking scornfully at C# (notice that I did not mention .NET or Windows or Microsoft &#8211; I said C#). But perhaps there are some out there and the blog series does attempt to provide them sufficient evidence to reconsider their opinions. But reading through the posts made me think, there&#8217;s at least one good reason Java programmers can choose to celebrate and look forward to rather than feel worried about Java. And all these capabilities are available for the asking on their preferred platform &#8211; the JVM and in an interoperable and incrementally migratable way from their current code bases. &#8211; Scala.</p>
<p>Now, believe me you, scala capabilities extend far beyond those I describe below. But that further discovery is an adventure which readers are encouraged to conduct later. Also &#8211; I am only a little along that path of Scala discovery and still have distances to cover. So I won&#8217;t feel surprised if people are able to offer healthier and superior solutions to the ones I describe below. In fact, I would encourage them to do the same. But here&#8217;s something for all ye java citizens to feel good about.</p>
<p>Please note that it will be helpful if you review these two blog posts referred to above &#8211; since almost every example I refer to below, that I write using Scala, is based on the examples in these posts which are written in Java and C#. Thus, even after reading those posts, it might be useful to keep them open in other tabs. So that should you prefer to do so, you can refer to those Java and C# examples simultaneously as you read the Scala examples.</p>
<p><strong>Unified Type System</strong></p>
<p>Scala has types for the java primitives eg. Byte, Short, Int. Thus you can continue to deal with them as objects instead of having to specifically deal with them as primitives. All value classes inherit from AnyVal, whereas all others inherit from AnyRef, both in turn inheriting from Any. In addition there are a number of additional methods that are available on these types (eg. <a href="http://www.scala-lang.org/api/current/scala/runtime/RichInt.html">RichInt</a>). At the same time these types have <em>exactly</em> the same ranges as java primitives. Thus the scala compiler can choose to transform instances of such value types into corresponding Java primitive types. </p>
<p><strong>Farewell Checked Exceptions</strong></p>
<p>Goodbye. Adios. Au revoir, Vale. Checked Exceptions have been bid farewell. And I don&#8217;t think anyone&#8217;s less happy for it. But if you need to call Scala code from Java, you can choose to use the <em>@throws</em> annotation to mark your methods so that java code may treat these as thrown exceptions.</p>
<p><strong>Double Rainbow Accessors</strong></p>
<p>Another heavy weight boilerplate thats been waived goodbye is java bean style getter setters. Every non private member declared automatically gets a getter and setter free by default. In situations where you would want to override the default behaviour, you can choose to do so as well. Besides a particular construct called a case class further simplifies this and helps you create a class trivially with reasonable implementation of equals, toString etc. already rolled in. It is likely, that new keyboards continue to retain their gloss and continue to function far longer when coding in scala than in Java. A simple example of double rainbow accessors :</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">case</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> Meme <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> catchPhrase <span style="color: #000080;">:</span> String, &nbsp;<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> url<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span><br />
<br />
<span style="color: #008000; font-style: italic;">// Notice: class members are declared as default constructor parameters. No further</span><br />
<span style="color: #008000; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; declaration required again.</span><br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> MemeAdvanced <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">private</span></a> <span style="color: #F78811;">&#91;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#93;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> cp<span style="color: #000080;">:</span> String, <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">private</span></a> <span style="color: #F78811;">&#91;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a><span style="color: #F78811;">&#93;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> u<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#123;</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// Since these are private fields, they can be wrapped using </span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// getters / setters as follows which can be modified to suit any non-typical</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// expectations eg. validations</span><br />
&nbsp; <br />
&nbsp; <span style="color: #008000; font-style: italic;">// if the above parameter declarations did not have private qualifier,</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// the methods below would be automatically provided, whereas if declaration contained</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// val instead of var, only the getter would get provided.</span><br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> catchPhrase <span style="color: #000080;">=</span> cp<br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> catchPhrase<span style="color: #000080;">_=</span><span style="color: #F78811;">&#40;</span>s<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>cp <span style="color: #000080;">=</span> s<span style="color: #F78811;">&#125;</span><br />
&nbsp; <br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> url <span style="color: #000080;">=</span> u<br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> url<span style="color: #000080;">_=</span><span style="color: #F78811;">&#40;</span>s<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span> u <span style="color: #000080;">=</span> s<span style="color: #F78811;">&#125;</span><br />
<span style="color: #F78811;">&#125;</span><br />
<br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> DoubleRainbow <span style="color: #F78811;">&#123;</span><br />
&nbsp; <br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> main<span style="color: #F78811;">&#40;</span>args <span style="color: #000080;">:</span> Array<span style="color: #F78811;">&#91;</span>String<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:</span> Unit <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// using case classes</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> meme <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> Meme<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;foo&quot;</span>,<span style="color: #6666FF;">&quot;bar&quot;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; meme.<span style="color: #000000;">catchPhrase</span> <span style="color: #000080;">=</span> <span style="color: #6666FF;">&quot;Rick roll'd&quot;</span><br />
&nbsp; &nbsp; meme.<span style="color: #000000;">url</span> <span style="color: #000080;">=</span> <span style="color: #6666FF;">&quot;http://www.youtube.com/watch?v=EK2tWVj6lXw&quot;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>meme.<span style="color: #000000;">catchPhrase</span><span style="color: #F78811;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// using normal classes</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> meme2 <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> MemeAdvanced<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;foo&quot;</span>,<span style="color: #6666FF;">&quot;bar&quot;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; meme2.<span style="color: #000000;">catchPhrase</span> <span style="color: #000080;">=</span> <span style="color: #6666FF;">&quot;Rick roll'd&quot;</span><br />
&nbsp; &nbsp; meme2.<span style="color: #000000;">url</span> <span style="color: #000080;">=</span> <span style="color: #6666FF;">&quot;http://www.youtube.com/watch?v=EK2tWVj6lXw&quot;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>meme.<span style="color: #000000;">catchPhrase</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; <span style="color: #F78811;">&#125;</span><br />
<span style="color: #F78811;">&#125;</span></div></td></tr></tbody></table></div>
<p><strong>Initialisers</strong></p>
<p>There&#8217;s a bunch of new initialisation capabilities eg. initialising using field names</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> meme <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> Meme<span style="color: #F78811;">&#40;</span>catchPhrase<span style="color: #000080;">=</span><span style="color: #6666FF;">&quot;blub&quot;</span>, url<span style="color: #000080;">=</span><span style="color: #6666FF;">&quot;blub2&quot;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>meme.<span style="color: #000000;">catchPhrase</span><span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p>or  you can initialise a collection by passing a series of arguments to the constructor</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> digits <span style="color: #000080;">=</span> List<span style="color: #F78811;">&#91;</span>Int<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">0</span>,<span style="color: #F78811;">1</span>,<span style="color: #F78811;">2</span>,<span style="color: #F78811;">3</span>,<span style="color: #F78811;">4</span>,<span style="color: #F78811;">5</span>,<span style="color: #F78811;">6</span>,<span style="color: #F78811;">7</span>,<span style="color: #F78811;">8</span>,<span style="color: #F78811;">9</span><span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p>or you could choose to load up a map with a bunch of associations at instantiation time</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> keywordsMapping <span style="color: #000080;">=</span> Map<span style="color: #F78811;">&#91;</span>String,String<span style="color: #F78811;">&#93;</span> <span style="color: #F78811;">&#40;</span> <span style="color: #6666FF;">&quot;super&quot;</span> -<span style="color: #000080;">&gt;</span> <span style="color: #6666FF;">&quot;base&quot;</span>, <span style="color: #6666FF;">&quot;boolean&quot;</span> -<span style="color: #000080;">&gt;</span> <span style="color: #6666FF;">&quot;bool&quot;</span>, <span style="color: #6666FF;">&quot;import&quot;</span> -<span style="color: #000080;">&gt;</span> <span style="color: #6666FF;">&quot;using&quot;</span> <span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>digits.<span style="color: #000000;">head</span> + <span style="color: #6666FF;">&quot; &quot;</span> + keywordsMapping<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;boolean&quot;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p><strong>Verbatim (Multiline) Strings</strong></p>
<p>That isn&#8217;t too hard with scala too. Just use triple consecutive double quotes delimiter (&#8220;&#8221;")to make the string span multiple lines.</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> input <span style="color: #000080;">=</span> <span style="color: #6666FF;">&quot;&quot;</span><span style="color: #6666FF;">&quot;Multiline<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 325-532-4521&quot;</span><span style="color: #6666FF;">&quot;&quot;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>input<span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p><strong>Methods as first class citizens</strong></p>
<p>Missing function pointers after you moved away from C / C++? Thats available too .. in a typesafe manner.</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// declare a function pointer which takes a string as an input</span><br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// and outputs the same</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> normalizeOp <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span>input<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> input reverse<span style="color: #000080;">;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>normalizeOp<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;abcd&quot;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// compiler error : normalizeOp = (input: String) =&gt; 0;</span><br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// thus the type of normalizeOp can no longer be changed</span><br />
<br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// but it can be used to point to a different method instead</span><br />
&nbsp; &nbsp; normalizeOp <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span>input<span style="color: #000080;">:</span> String<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> input trim<span style="color: #000080;">;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>normalizeOp<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot; &nbsp;foo &nbsp;bar &nbsp;&quot;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p><strong>Event</strong></p>
<p>Now, scala doesn&#8217;t have a built in Event class which has its automatic hardwired publish subscribe capabilities. But one of the themes you will find in this post is that Scala lives up to its name which really refers to it being a scalable language. So a whole set of language constructs can actually be built into the language by writing other code. Thats why sometimes it feels somewhat like a meta-language, a language to write your own language structures in. The construct below is rather simple and straight-forward, but we shall see creating your own language control structure like constructs later as well.</p>
<p>Here&#8217;s a simple event class</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> Event <span style="color: #F78811;">&#123;</span><br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> l <span style="color: #000080;">=</span> List<span style="color: #F78811;">&#91;</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> Unit<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><br />
<br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> +<span style="color: #000080;">=</span><span style="color: #F78811;">&#40;</span>f<span style="color: #000080;">:</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> Unit<span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Unit <span style="color: #000080;">=</span> l <span style="color: #000080;">=</span> f <span style="color: #000080;">::</span> l &nbsp; <br />
&nbsp; <br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> apply<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> l map <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><br />
<span style="color: #F78811;">&#125;</span></div></td></tr></tbody></table></div>
<p>It declares a list of listeners <em>l</em> and allows listening functions to be registered against the event getting triggered (which in this case would be the += method. Finally since the event is triggered using event() construct in C#, we here define the apply function, which will get triggered whenever e() is invoked, e being the instance of any event. Note: I&#8217;ve deliberately used single character names for the fields to allow you to focus on the other constructs &#8211; not a good coding practice.</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> Button <span style="color: #F78811;">&#123;</span><br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> action <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> Event<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">;</span><br />
&nbsp; <br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> performClick<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> onClick<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; <br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">private</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> onClick<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// this should call the apply() method</span><br />
&nbsp; &nbsp; action<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; <span style="color: #F78811;">&#125;</span><br />
<span style="color: #F78811;">&#125;</span><br />
<br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> EventDriver <span style="color: #F78811;">&#123;</span><br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> performAction<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;Work!&quot;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; <span style="color: #F78811;">&#125;</span><br />
&nbsp; <br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> main<span style="color: #F78811;">&#40;</span>args <span style="color: #000080;">:</span> Array<span style="color: #F78811;">&#91;</span>String<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:</span> Unit <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> button <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> Button<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// add a method as a listener</span><br />
&nbsp; &nbsp; button.<span style="color: #000000;">action</span> +<span style="color: #000080;">=</span> performAction<br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// trigger the event</span><br />
&nbsp; &nbsp; button.<span style="color: #000000;">performClick</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> &nbsp; &nbsp;<br />
&nbsp; <span style="color: #F78811;">&#125;</span><br />
<span style="color: #F78811;">&#125;</span></div></td></tr></tbody></table></div>
<p>So does one really need to have a Event baked into the language ? Apparently not really when it is a scalable language.</p>
<p><strong>Lambda expressions</strong></p>
<p>Indeed one of the strong points of this language. A simple lambda function is given below</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> isUniverseAnswer <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span>x<span style="color: #000080;">:</span> Int<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> x <span style="color: #000080;">==</span> <span style="color: #F78811;">42</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>isUniverseAnswer<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">42</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>isUniverseAnswer<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">43</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p>There, it isn&#8217;t so hard. But what when you want to define a lambda on the fly ? Turns out thats quite straight forward too.</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> users <span style="color: #000080;">=</span> List<span style="color: #F78811;">&#91;</span>User<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#40;</span>User<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;Five&quot;</span>,<span style="color: #F78811;">5</span><span style="color: #F78811;">&#41;</span>, User<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;Fifteen&quot;</span>,<span style="color: #F78811;">15</span><span style="color: #F78811;">&#41;</span>, User<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;TwentyFive&quot;</span>, <span style="color: #F78811;">25</span><span style="color: #F78811;">&#41;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; User<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;Ten&quot;</span>,<span style="color: #F78811;">10</span><span style="color: #F78811;">&#41;</span>, User<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;Twenty&quot;</span>, <span style="color: #F78811;">20</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// Note : the argument passed to the filter() method is the lambda, and the _ refers </span><br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; to each User object passed in</span><br />
&nbsp; &nbsp; println <span style="color: #F78811;">&#40;</span>users filter <span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>.<span style="color: #000000;">age</span> <span style="color: #000080;">&lt;</span> <span style="color: #F78811;">18</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p>And if we did want to explore closures, there&#8217;s good support there too.</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">var</span></a> counter <span style="color: #000080;">=</span> <span style="color: #F78811;">0</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> action <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> <span style="color: #F78811;">&#123;</span>counter +<span style="color: #000080;">=</span> <span style="color: #F78811;">1</span><span style="color: #000080;">;</span> println<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;counter = &quot;</span> + counter<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#125;</span><br />
&nbsp; &nbsp; action<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; action<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p>As Jack Sparrow would&#8217;ve said, <em>&#8220;savvy?&#8221;</em></p>
<p><strong>Extension methods</strong></p>
<p>The exact details of how some of these capabilities are made to work are beyond the scope of this post, but scala allows for a lot of new extension methods on basic built in types through a variety of additional classes, and the same capabilities can be used by you to define any additional extension methods. As a teaser example, we&#8217;ll use the reverse method defined in the WrappedString type which helps extend the same method to be used with strings.</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">println<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;Example&quot;</span> reverse<span style="color: #F78811;">&#41;</span></div></td></tr></tbody></table></div>
<p><strong>Return Multiple Values</strong></p>
<p>Thats very intuitive and simple too.</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> ReturnMultiple <span style="color: #F78811;">&#123;</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// this method returns two values</span><br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> addOneToAll<span style="color: #F78811;">&#40;</span>a<span style="color: #000080;">:</span> Int, b<span style="color: #000080;">:</span> Int<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #F78811;">&#40;</span>a + <span style="color: #F78811;">1</span>, b + <span style="color: #F78811;">1</span><span style="color: #F78811;">&#41;</span><br />
<br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> main<span style="color: #F78811;">&#40;</span>args <span style="color: #000080;">:</span> Array<span style="color: #F78811;">&#91;</span>String<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:</span> Unit <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> <span style="color: #F78811;">&#40;</span>c, d<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> addOneToAll<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">3</span>,<span style="color: #F78811;">4</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span>c + <span style="color: #6666FF;">&quot;,&quot;</span> + d<span style="color: #F78811;">&#41;</span><br />
&nbsp; <span style="color: #F78811;">&#125;</span><br />
<span style="color: #F78811;">&#125;</span></div></td></tr></tbody></table></div>
<p><strong>Null-coalescing operator</strong></p>
<p>To the best of my knowledge scala doesn&#8217;t have this operator. The C# code looks like follows which allows the first non-null value amongst a, b, and c to be set as the result.</p>
<div class="codecolorer-container csharp dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6666cc; font-weight: bold;">string</span> result <span style="color: #008000;">=</span> a <span style="color: #008000;">??</span> b <span style="color: #008000;">??</span> c</div></td></tr></tbody></table></div>
<p>Well, we&#8217;ll build that operator (I&#8217;m sure someone will suggest a better option than the one below)</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">class</span></a> Nullable<span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> t<span style="color: #000080;">:</span> AnyRef<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> <span style="color: #000080;">??</span><span style="color: #F78811;">&#40;</span>b<span style="color: #000080;">:</span> AnyRef<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">if</span></a> <span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a>.<span style="color: #000000;">t</span> <span style="color: #000080;">!=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">this</span></a>.<span style="color: #000000;">t</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">else</span></a> b<br />
<span style="color: #F78811;">&#125;</span><br />
<br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> NullCoalescing <span style="color: #F78811;">&#123;</span><br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">implicit</span></a> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> objToNullable<span style="color: #F78811;">&#40;</span>a<span style="color: #000080;">:</span> AnyRef<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:</span> Nullable <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> Nullable<span style="color: #F78811;">&#40;</span>a<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#125;</span><br />
<br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> main<span style="color: #F78811;">&#40;</span>args <span style="color: #000080;">:</span> Array<span style="color: #F78811;">&#91;</span>String<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:</span> Unit <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;hello&quot;</span> <span style="color: #000080;">??</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a> <span style="color: #000080;">??</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #000080;">:</span> AnyRef<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">??</span> <span style="color: #6666FF;">&quot;world&quot;</span> <span style="color: #000080;">??</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a><span style="color: #000080;">:</span> AnyRef<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">??</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">null</span></a> <span style="color: #000080;">??</span> <span style="color: #6666FF;">&quot;foobar&quot;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; <span style="color: #F78811;">&#125;</span><br />
<span style="color: #F78811;">&#125;</span></div></td></tr></tbody></table></div>
<p>If you see the three println statements, they show how the newly defined ?? operator can deliver the same semantics. Since null cannot help the type inferencing engine, in the latter two println statements &#8211; it has been explicitly cast to AnyRef.</p>
<p><strong>Automatic Resource Management</strong></p>
<p>Apparently C# has a built in capability of automatic resource management by using the keyword <em>using</em>. Alas Scala doesn&#8217;t. But building it is hardly much effort. So here goes :</p>
<div class="codecolorer-container scala dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br /></div></td><td><div class="scala codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">import</span></a> java.<span style="color: #000000;">io</span>.<span style="color: #000000;">FileInputStream</span><br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">import</span></a> java.<span style="color: #000000;">io</span>.<span style="color: #000000;">DataInputStream</span><br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">import</span></a> java.<span style="color: #000000;">io</span>.<span style="color: #000000;">InputStreamReader</span><br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">import</span></a> java.<span style="color: #000000;">io</span>.<span style="color: #000000;">BufferedReader</span><br />
<a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">object</span></a> AutomaticResourceManagement <span style="color: #F78811;">&#123;</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// This is a structural type. Any type which has methods which match the two</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// desired signatures specified below can be used wherever this type is expected</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// ** no inheritance required **</span><br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">type</span></a> ReadableAndCloseable <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> close<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #000080;">:</span> Unit <span style="color: #000080;">;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> readLine<span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:</span> String<span style="color: #F78811;">&#125;</span><br />
&nbsp; <br />
&nbsp; <span style="color: #008000; font-style: italic;">// And to be able to define our own control structure, the second parameter to</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// using takes a function block which takes a ReadableAndCloseable as input</span><br />
&nbsp; <span style="color: #008000; font-style: italic;">// and returns nothing.</span><br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> using<span style="color: #F78811;">&#40;</span>resource<span style="color: #000080;">:</span> ReadableAndCloseable<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#40;</span>f<span style="color: #000080;">:</span> ReadableAndCloseable <span style="color: #000080;">=&gt;</span> Unit<span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">try</span></a> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; f<span style="color: #F78811;">&#40;</span>resource<span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #F78811;">&#125;</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">finally</span></a> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; println<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;Closing resource&quot;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; resource.<span style="color: #000000;">close</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #F78811;">&#125;</span><br />
&nbsp; <span style="color: #F78811;">&#125;</span><br />
&nbsp; <br />
&nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">def</span></a> main<span style="color: #F78811;">&#40;</span>args <span style="color: #000080;">:</span> Array<span style="color: #F78811;">&#91;</span>String<span style="color: #F78811;">&#93;</span><span style="color: #F78811;">&#41;</span> <span style="color: #000080;">:</span> Unit <span style="color: #000080;">=</span> <span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">val</span></a> reader <span style="color: #000080;">=</span> <a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> BufferedReader<span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> InputStreamReader<span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> DataInputStream<span style="color: #F78811;">&#40;</span><a href="http://scala-lang.org"><span style="color: #0000ff; font-weight: bold;">new</span></a> FileInputStream<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;foo.txt&quot;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000; font-style: italic;">// Now you can be sure, the reader will get closed.</span><br />
&nbsp; &nbsp; using<span style="color: #F78811;">&#40;</span>reader<span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #F78811;">&#40;</span>resource<span style="color: #F78811;">&#41;</span> <span style="color: #000080;">=&gt;</span> println<span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;First line is: &quot;</span> + resource.<span style="color: #000000;">readLine</span><span style="color: #F78811;">&#40;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #F78811;">&#125;</span><br />
&nbsp; <span style="color: #F78811;">&#125;</span><br />
<span style="color: #F78811;">&#125;</span></div></td></tr></tbody></table></div>
<p><strong>Summary</strong></p>
<p>Well there&#8217;s more in Scala. Lots more. And it takes some patient effort to learn it. We&#8217;ve hardly started to talk about the functional programming capabilities. Or its parallel collections. Or for that matters its pattern matching. Or even its ability to deal with Generics with specified Co and Contravariance. We haven&#8217;t gone that far. But all the seemingly distant capabilities &#8211; that seemed to be miles away in a different planet called .NET and a country called C#, are actually just a step away &#8211; using Scala. As a java programmer, I don&#8217;t think you should look down at C# .. just look forward to Scala <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=g7A3g_9b5gs:3P8ODUCSy-o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=g7A3g_9b5gs:3P8ODUCSy-o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=g7A3g_9b5gs:3P8ODUCSy-o:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=g7A3g_9b5gs:3P8ODUCSy-o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=g7A3g_9b5gs:3P8ODUCSy-o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=g7A3g_9b5gs:3P8ODUCSy-o:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/g7A3g_9b5gs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2011/05/why-java-folks-should-look-forward-to-scala/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2011/05/why-java-folks-should-look-forward-to-scala/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=why-java-folks-should-look-forward-to-scala</feedburner:origLink></item>
		<item>
		<title>The cloud just got stronger, even as AWS went down</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/Rp2MiPLPZnA/</link>
		<comments>http://blog.dhananjaynene.com/2011/04/the-cloud-just-got-stronger-even-as-aws-went-down/#comments</comments>
		<pubDate>Fri, 22 Apr 2011 09:41:20 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[iaas]]></category>
		<category><![CDATA[outage]]></category>

	<!-- AutoMeta Start -->
	<category>zones</category>
	<category>netflix</category>
	<category>redundancy</category>
	<category>impacted</category>
	<category>regions</category>
	<category>skynet</category>
	<category>infrastructures</category>
	<category>availability</category>
	<category>zones</category>
	<category>netflix</category>
	<category>redundancy</category>
	<category>impacted</category>
	<category>regions</category>
	<category>skynet</category>
	<category>infrastructures</category>
	<category>availability</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1082</guid>
		<description><![CDATA[So some parts of the AWS EC2 specifically related to EBS were non responsive or down yesterday. This was of course also supposed to be judgement day after skynet became self aware. Links between facts and fiction aside, the number of sites that got impacted was just quite large and at least some (not most) [...]]]></description>
			<content:encoded><![CDATA[<p>So some parts of the AWS EC2 specifically related to EBS were <a href="http://www.bloomberg.com/news/2011-04-21/amazon-com-says-some-web-services-for-businesses-not-available.html">non responsive or down yesterday</a>. This was of course also supposed to be <a href="http://blog.zap2it.com/pop2it/2011/04/april-21-2011-skynet-attacks-we-explain-the-terminator-date-confusion.html">judgement day after skynet became self aware</a>. Links between facts and fiction aside, the number of sites that got impacted was just quite large and at least some (not most) started wondering if cloud indeed is the way to go.</p>
<p>I think the cloud just became stronger. Even as many services go impacted, some didn&#8217;t. As an example Netflix was able to continue with its services. See Slide 33 in a recently conducted <a href="http://www.slideshare.net/adrianco/netflix-in-the-cloud-2011">presentation</a> of its architecture. I am certain there were many others who also were able to ride the storm. Since they had not just planned for redundancy of equipments but the architecture had accounted for disaster recovery (redundancy of locations). And many others who got impacted and put their customers through undeserved anguish still perhaps learnt a lot. A lot that they could&#8217;ve done differently. </p>
<p>What is interesting about &#8220;a lot that they could&#8217;ve done differently&#8221; is that cloud infrastructure as a service opens up a few more options to ensure high availability. Amazon AWS apparently has 5 regions and the US East region which got affected has at least four availability zones. It was one of that availability zone which got substantially impacted. Though in fairness the impact seems to have spread into other availability zones, something that shouldn&#8217;t ideally have happened. I am sure there probably were a lot of things AWS probably learnt and perhaps would do differently. But the same applies now to AWS customers as well. Some may choose to lose faith in the cloud. But many others might choose to realise that cloud infrastructures have the potential to offer so much more redundancy and options to high availability. Its just that one needs to realise that cloud data centers are not infallible, and after being aware of all the redundancy options, one just needs to design the right way to leverage them. </p>
<p>And how does one leverage them ? AWS has multiple availability zones. An application should ideally leverage at least two. If you read the Netflix presentation I referred to, Netflix apparently uses three. Do not assume the servers will not go down. Assume it is possible that at least one availability zone could go down. Make sure you have the systems to quickly activate, systems in the alternative availability zone. For that you will need to find ways to keep data current across availability zones. Also find ways to ensure you have the ability to quickly switch to and fro between availability zones. More advanced options could include concurrently active systems across availability zones or those spread across AWS regions or even between AWS and other vendors.</p>
<p>There&#8217;s little if any learnings here that are specific to AWS. They are indeed applicable in general to cloud based infrastructure as a service providers. But unless you are a part of a Fortune 500 or equivalent it is very unlikely that your internal infrastructure will offer as many options for redundancy as at least some of the larger infrastructure as a service providers could. Which is why I believe even if some may choose to switch back to the seeming comfort of private infrastructure, many currently using private infrastructure are likely to look at today&#8217;s events and realise that the public cloud actually offers so many better options for building highly available systems. The issues are not yet fully resolved. And many customers still perhaps are not being served. And while one hopes not, it could so happen that there could be further disruptions. But I find them really aspects of dealing with a learning curve as one transitions across class and scale of infrastructures. Ignoring the short term pain, and looking at it a little bit in the longer term, whichever way one really looks at it, I think the cloud just became stronger.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=Rp2MiPLPZnA:7rB6c-PHBVE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=Rp2MiPLPZnA:7rB6c-PHBVE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=Rp2MiPLPZnA:7rB6c-PHBVE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=Rp2MiPLPZnA:7rB6c-PHBVE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=Rp2MiPLPZnA:7rB6c-PHBVE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=Rp2MiPLPZnA:7rB6c-PHBVE:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/Rp2MiPLPZnA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2011/04/the-cloud-just-got-stronger-even-as-aws-went-down/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2011/04/the-cloud-just-got-stronger-even-as-aws-went-down/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=the-cloud-just-got-stronger-even-as-aws-went-down</feedburner:origLink></item>
		<item>
		<title>Monads in an Object Oriented context</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/lUh1mbQQ9_E/</link>
		<comments>http://blog.dhananjaynene.com/2010/08/monads-in-an-object-oriented-context/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 15:14:58 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[functional programming]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[monads]]></category>
		<category><![CDATA[object orientation]]></category>
		<category><![CDATA[ood]]></category>

	<!-- AutoMeta Start -->
	<category>monad</category>
	<category>monadic</category>
	<category>container</category>
	<category>monads</category>
	<category>monad</category>
	<category>monadic</category>
	<category>container</category>
	<category>monads</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1056</guid>
		<description><![CDATA[The other day I was referred to a blog post jQuery is a Monad. That is an interesting post which if you have any interest in Monads should read. My first thought was that jQuery was another implementation of Fluent Interface and it just did not strike me as a monadic construct. There are blog [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I was referred to a blog post <a href="http://importantshock.wordpress.com/2009/01/18/jquery-is-a-monad/">jQuery is a Monad</a>. That is an interesting post which if you have any interest in Monads should read. My first thought was that jQuery was another implementation of Fluent Interface and it just did not strike me as a monadic construct.</p>
<p>There are blog posts which take an essential thought or a message and by putting together various arguments bring it to some logical conclusion. This post is not one of them. It just describes the results of my thought process which started off contesting the assertion, to accepting it and then realising that either way, it really didn&#8217;t matter a whole lot. I don&#8217;t claim it to be sufficiently accurate except to state that it is accurate only to the best of my belief and understanding. Pointers to any inaccuracies or alternate interpretations in the comments shall be gratefully received. And yes, this post in the end reaches a somewhat boring conclusiion.</p>
<p>Having got that little expectation management out of the way, lets get back to monads, jQuery and Object Orientation. Writing a tutorial on Monads is a rite of passage for many. Thats something I&#8217;ve never done. And I don&#8217;t wish to, but I cannot escape the fact that I&#8217;m going to have to introduce monads to those who are as challenged in their understanding as I am. </p>
<p><strong>What are Monads ?</strong> </p>
<p>I&#8217;ll give you the loose idea. Whenever a function completes any computation, the results of the computations are often returned as the return value of the function. But every once in a while you need a container around that return value. A container to store the state of a computation, sometimes with additional metadata or historical annotations for use later. At its very basis, a monad is a container for storing computations and being the container to be carried between functions. Think of it as a shipping container if you will, which moves materials between factories &#8211; the factories being various functions which operate on the contents of that container. </p>
<p>But it takes more for a monad to be a monad than just being a container. Given any content, the monad should be able to construct itself by wrapping itself around the content. Thats what the source factory invokes when it fills up the container with goods. Some prefer to call it a type constructor &#8211; the type here being the container, or the monad (which may internally contain goods of various types, but I get ahead of myself).</p>
<p>In addition once the container reaches the destination factory, unlike typical container, this one does not just allow its contents to be unloaded. Nay, that would make it too simple. In this case, the container has to be taken to a factory where it allows a robotic arm of the factory to plug into a receptacle it provides, which the factory can use to extract the underlying values, often one at a time. The factory further processes these goods, which again come out at the other end of the factory as a different set of containers. And it is quite likely that the type of the goods in the new containers could&#8217;ve changed. </p>
<p>That in essence is a monad. Easy, right ? I&#8217;m sure not and I&#8217;m now only going to make it a bit harder.</p>
<p><strong>The wikipedia, definition of monad <a href="http://en.wikipedia.org/wiki/Monad_(functional_programming)">Monad</a></strong></p>
<p>I&#8217;m just going to let you read the definition as provided by wikipedia.</p>
<blockquote><p>
A monad is a construction that, given an underlying type system, embeds a corresponding type system (called the monadic type system) into it (that is, each monadic type acts as the underlying type). This monadic type system preserves all significant aspects of the underlying type system, while adding features particular to the monad.<br />
The usual formulation of a monad for programming is known as a Kleisli triple, and has the following components:</p>
<ol>
<li>A type construction that defines, for every underlying type, how to obtain a corresponding monadic type. In Haskell&#8217;s notation, the name of the monad represents the type constructor. If M is the name of the monad and t is a data type, then &#8220;M t&#8221; is the corresponding type in the monad.
</li>
<li>A unit function that maps a value in an underlying type to a value in the corresponding monadic type. The result is the &#8220;simplest&#8221; value in the corresponding type that completely preserves the original value (simplicity being understood appropriately to the monad). In Haskell, this function is called return due to the way it is used in the do-notation described later. The unit function has the polymorphic type t→M t.
</li>
<li>A binding operation of polymorphic type (M t)→(t→M u)→(M u), which Haskell represents by the infix operator >>=. Its first argument is a value in a monadic type, its second argument is a function that maps from the underlying type of the first argument to another monadic type, and its result is in that other monadic type. The binding operation can be understood as having four stages:
<ol>
<li>The monad-related structure on the first argument is &#8220;pierced&#8221; to expose any number of values in the underlying type t.
</li>
<li>The given function is applied to all of those values to obtain values of type (M u).
</li>
<li>The monad-related structure on those values is also pierced, exposing values of type u.
</li>
<li>Finally, the monad-related structure is reassembled over all of the results, giving a single value of type (M u).
</li>
</ol>
</li>
</ol>
<p>In object-oriented programming terms, the type construction would correspond to the declaration of the monadic type, the unit function takes the role of a constructor method, and the binding operation contains the logic necessary to execute its registered callbacks (the monadic functions).</p>
<p>In practical terms, a monad (seen as special result values carried throughout the pipeline) stores function results and side-effect representations. This allows side effects to be propagated through the return values of functions without breaking the pure functional model.
</p></blockquote>
<p><strong>The bind operation</strong></p>
<p>So coming back to the container analogy, the container is the monad, the goods are the underlying types, and the factory is a function which takes a underlying type and spews out another monad which contains the newly manufactured goods. There is a difference to be noted, the container doesn&#8217;t go into the factory, its the factory thats plugged into the monad through the bind operation, which triggers the processing. Also note that the output of each such factory is not just goods, but containers of such goods it manufactures.</p>
<p>There, you can now imagine a series of containers and factories, or monads and functions which are sequenced to assemble a pipeline to produce the desired goods / computations.</p>
<p>Before we go on to how this works in OO, I would like to spend some more time on the function thats provided to the binding operation. This function accepts the individual contents of the incoming container and returns a container with the newly manufactured goods. A somewhat similar function is used when using map operations on containers eg. Lists. So if I had a list of integers, and I wrote a function which doubled their values, then the map operation would be written in python as :</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> twice<span style="color: black;">&#40;</span>val<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span> * val<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">map</span><span style="color: black;">&#40;</span>twice<span style="color: #66cc66;">,</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">#Expected output is :['2', '4', '6', '8', '10']</span></div></td></tr></tbody></table></div>
<p>This is a good example where the container (tuple) is unbundled inside the map operation, each constituent value of the list is passed to the <em>twice</em> function, and all the results of the twice function are reassembled into yet another container (list). The type of the constituents also changed from ints to str (string) along the way. To be a strictly monadic construct, the twice function should&#8217;ve returned not just the double of the value, but a double contained in some other container (either a tuple or a list), and the map function should&#8217;ve extract the individual strings from each of the individual tuples/lists and constructed a final tuple / list out of the same.</p>
<p>While unlikely to be confused as so, let me restate for clarity, the <em>map</em> function is not the monad. The tuple and the lists are the monads here. The map function is an example of the contextual capabilities that monads expect from their environment (eg. via and around the bind operator in haskell). And <em>twice</em> is the operation thats performed on the monad. Again to restate, the monadic chain is like a set of factories that spew out containers, which allow other factories to plug into them and in turn extract the contents and then spew out even more containers.</p>
<p><strong>Monads and Object Orientation</strong></p>
<p>So how does this work in an object oriented context ?</p>
<p>Lets take rules 1 and 2 of a monad. If I was to declare a class which had a constructor which took in a value and then wrapped it, then I would satisfy these two rules for being then be able to suggest that the class is a monad. However the rule 3 gets a little bit more interesting. Object oriented languages have the <em>&#8220;.&#8221;</em> operator which is somewhat analogous to the <em>do block</em> which can chain operations. So if I was to write <em>o.foo()</em> that would be equivalent of suggesting that I invoke the method foo() on the object which being a member method of the class has access to all the object internals and thus is able to access the wrapped value and do the necessary computations. Now if <em>foo()</em> were to return any object again of a class which satisfies these very rules, then I would be able to say that this class along with its member function foo() is a reasonable object oriented analogy of the monad. And I would be able to start chaining the methods as in <em>o.foo().bar().baz()</em></p>
<p>Whoa! let me restate that again. If a class, has a constructor which takes a value and wraps that value, and has a number of additional member functions which each operate on these underlying values and return an instance of either the same object or another object of a class which follows the same rules, then I can say that that particular class is a monad. Incidentally thats exactly what fluent interfaces do, except that they do not have any specific expectation of wrapping. And a large number of classes may incidentally fit this description. And if jQuery is a monad, so are all of them.</p>
<p>Well, we did relax a few constraints along the way. First of all the functions are not stand alone functions. They are member methods which have direct access to the underlying wrapped value. Secondly they themselves don&#8217;t return a monad around an individual item in a collection. They return a monad around the entire collection of values. Thus the complexities and capabilities of the do block and the bind function are substantially simplified when using the &#8220;.&#8221; operator. And finally going back to the container analogy, the class defines and consists of both the containers and the factories. Seems like the threshold for stating a particular class is a monad is actually quite low. Turns out we reached a boring end. And it seems we are not much wiser at least in terms of any specific conclusions or insights. But every once in a while sometime the journey is more exciting than its end. For me this did seem like one.</p>
<p><strong>Why are objects simple and monads complex ?</strong></p>
<p>At least for me the above was true. Turns out objects collate related data and functions together into one class. Also the do block and bind operator on an object is very simple. So for many especially coming from the OO school, objects are well understood. On the other hand understanding the requirements of monadic constructs takes quite some time. So there&#8217;s a lot of gray cells that need to be exercised to start understanding what a monad is and how the various requirements for a monadic construct can be satisfied. And when mapping between monads, and objects which can also be seen to be monads, a lot of that complexity is either partially waived (eg. functions returning monads, the infrastructure around bind operators unbundling and bundling monads) or just simplified (functions and underlying values being colocated in the same class, the &#8220;.&#8221; operator being a far more simplified version of do block). But after some substantial headaches, it does start to seem that perhaps, just perhaps, monads aren&#8217;t so complicated after all <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>So is jQuery a monad ? I believe one could choose to be very pedantic and point out minor issues with that assertion. Or one could accept that the intent of monadic sequences are well represented in jQuery chains and accept it as one. I started with the former and ended at the latter position. Would I express that jQuery is a monad ? To the monadically challenged &#8211; No. That obfuscates far more than it enlightens. To them I would say jQuery is a fluent interface which allows continuous chaining of operations on an underlying set of dom objects. And is there a big &#8220;Aha moment&#8221; when one realises that jQuery is a monad ? I couldn&#8217;t find one. While the journey of trying to understand monads and correlate it with monads was very exciting, at least the OO practitioner in me is unlikely to have missed much had I not known that. But I got to understand monads better &#8211; and thats well worth the time, and all the headspinning.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=lUh1mbQQ9_E:eItUlJ8dUFU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=lUh1mbQQ9_E:eItUlJ8dUFU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=lUh1mbQQ9_E:eItUlJ8dUFU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=lUh1mbQQ9_E:eItUlJ8dUFU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=lUh1mbQQ9_E:eItUlJ8dUFU:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=lUh1mbQQ9_E:eItUlJ8dUFU:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/lUh1mbQQ9_E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/08/monads-in-an-object-oriented-context/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/08/monads-in-an-object-oriented-context/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=monads-in-an-object-oriented-context</feedburner:origLink></item>
		<item>
		<title>A case for non leaky dual abstractions.</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/1ozGiihBluo/</link>
		<comments>http://blog.dhananjaynene.com/2010/08/a-case-for-non-leaky-dual-abstractions./#comments</comments>
		<pubDate>Thu, 26 Aug 2010 15:37:38 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[abstractions]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[implementation]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[ood]]></category>

	<!-- AutoMeta Start -->
	<category>backend</category>
	<category>frontend</category>
	<category>leaky</category>
	<category>abstractions</category>
	<category>robustness</category>
	<category>inapplicable</category>
	<category>leak</category>
	<category>mould</category>
	<category>backend</category>
	<category>frontend</category>
	<category>leaky</category>
	<category>abstractions</category>
	<category>robustness</category>
	<category>inapplicable</category>
	<category>leak</category>
	<category>mould</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1042</guid>
		<description><![CDATA[A long long time ago, I worked on a fairly complex piece of design. And like any well behaved designer, I broke it down into a number of abstractions that made it manageable. I gave the abstractions funny sounding names. And before long I found those abstractions finding their way into the user interface. Abstractions [...]]]></description>
			<content:encoded><![CDATA[<p>A long long time ago, I worked on a fairly complex piece of design. And like any well behaved designer, I broke it down into a number of abstractions that made it manageable. I gave the abstractions funny sounding names. And before long I found those abstractions finding their way into the user interface. Abstractions which made no sense to the end user. </p>
<p>That experience taught me a good lesson. In attempting to deal with complexity, I was attempting to come up with the appropriate abstractions in a very bottom up way. So, strategic closure (of the Open Closed Principle), dependency inversion principle, et. al. all found their way into these abstractions I was modeling. These abstractions represented themselves via the various programmatic interfaces in the software design and their roles. At the same time there was a different perspective of the software. The way the end users would&#8217;ve preferred to see that software. The abstractions the way the end users saw the system were sometimes different than the underlying abstractions I modeled. </p>
<p>In a good design, the two abstractions should line up, and if there is an inconsistency, there is probably an issue with the design. Certainly this could be an issue in some cases. However in many cases the underlying backend might be built to offer far more capabilities than what are being exposed through the early version of the user interfaces. Probably there are multiple intents for which the software is being designed, and the particular user interface on table is just one of them. Probably, the underlying complexity of the back end is way too high which requires a very different nature of bottom up abstractions, which are different from the top down ones. Frankly, the reason doesn&#8217;t matter. Even after so many years, I look back and am comfortable with the thought that there needed to be two abstractions &#8211; one top down and one bottom up, one front end and one backend.</p>
<p>Fast forward many years. Another example helped me further attain some insight into the matter. We had a bunch of mobile smartphones floating around with the traditional PC UI abstractions being carried over into their design. Along came an iPhone &#8211; which rethought the interface the way users would&#8217;ve preferred to see the interface. Now iPhone was built on a traditional operating system. So it had the same abstractions that these operating systems have in the backend. However it decided to change some of the front end abstractions &#8211; in tune with the target market and the device / form factor peculiarities. Did the iPhone change the backend abstractions baked into its software &#8211; most likely not. However it changed the frontend abstractions, just enough to make the experience really simple and easy for its users.</p>
<p>As an engineer, I have lived with the regret of allowing backend abstractions to leak into the front end. But I have learnt something along the way. </p>
<ul>
<li>Don&#8217;t let the inapplicable frontend abstractions leak into the backend. This is especially true for most reasonably complex software. Strictly top down design can lead to a lot of brittleness in the long run, requiring very substantial surgery eventually.</li>
<li>Don&#8217;t let the inapplicable backend abstractions leak into the frontend. In most cases this is a usability nightmare. &#8217;nuff said.</li>
<li>Realise that you have to simultaneously service independent expectations ie. robustness of usability and robustness of modeling. Work with both the abstractions to mould each of them well: Work your frontend abstractions well enough to mould them to reflect the use cases of the software in the most usable manner.  Work with the backend abstractions to let them emerge from the problem space you are trying to resolve at the backend. Now make sure you work with both of them to map them into each in a reasonably smooth fashion. This is easier said than done. But doing it is whats necessary.</li>
</ul>
<p>PS: I am not referring to what is conventionally referred to as leaky abstractions, where the implementation leaks into an abstraction. I am referring to a set of frontend and backend abstractions leaking into each other. However if all the backend abstractions were to be treated as an implementation, then this would be a case of leaky abstractions as well.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1ozGiihBluo:c_Xuj1ke7b0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1ozGiihBluo:c_Xuj1ke7b0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=1ozGiihBluo:c_Xuj1ke7b0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1ozGiihBluo:c_Xuj1ke7b0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=1ozGiihBluo:c_Xuj1ke7b0:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1ozGiihBluo:c_Xuj1ke7b0:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/1ozGiihBluo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/08/a-case-for-non-leaky-dual-abstractions./feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/08/a-case-for-non-leaky-dual-abstractions./?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-case-for-non-leaky-dual-abstractions.</feedburner:origLink></item>
		<item>
		<title>Programming Languages should be Simple (or My ideal programming language)</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/tBGxM_aa8Uw/</link>
		<comments>http://blog.dhananjaynene.com/2010/08/my-ideal-programming-language/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 06:34:27 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[software]]></category>

	<!-- AutoMeta Start -->
	<category>inferencing</category>
	<category>ideal</category>
	<category>scala</category>
	<category>disappointed</category>
	<category>boilerplate</category>
	<category>clojure</category>
	<category>interop</category>
	<category>accessible</category>
	<category>inferencing</category>
	<category>ideal</category>
	<category>scala</category>
	<category>disappointed</category>
	<category>boilerplate</category>
	<category>clojure</category>
	<category>interop</category>
	<category>accessible</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1022</guid>
		<description><![CDATA[I am disappointed with many of the newer languages which I earlier thought showed great promise of making programming easier, quicker, and more robust. And it boils down to one thing. Simplicity in learning. Having gone through substantial amounts of programming in C, C++, Java and Python, my quest for the &#8220;next&#8221; programming language remains [...]]]></description>
			<content:encoded><![CDATA[<p>I am disappointed with many of the newer languages which I earlier thought showed great promise of making programming easier, quicker, and more robust. And it boils down to one thing. Simplicity in learning. Having gone through substantial amounts of programming in C, C++, Java and Python, my quest for the &#8220;next&#8221; programming language remains unfulfilled. </p>
<p><strong>Why ?</strong></p>
<p>Programming should be simple. And it should be accessible. And when I mean accessible I mean people with IQ of approximately 100 should be able to write programs. I am disappointed that many of the trends seem to raise either the minimum IQ or the training time required to gain competency. And while that helps a community of the super brilliant, it does not make a substantial difference to programming in general. It remains esoteric and does not stoop to touch everybody. </p>
<p><strong>What ?</strong></p>
<p>So what are the features of my preferred programming language :</p>
<ul>
<li><strong>JRE support</strong>: Should run on the JRE with Java interop. Thats the dominant well engineered platform that runs across all classes of desktops, servers and devices. Additional support for CLR is a bonus but not mandatory.</li>
<li><strong>Simplicity</strong>: Should be fairly simple to read, learn and understand. Python is a good example. PHP is a great example (at a simpler class of problems). C++ and Scala not good examples.</li>
<li><strong>Multi paradigm</strong> : Should support both OO and FP constructs. eg. Scala and Python. Half hearted support to functional programming as with python discouraged. Ditto with passionate support for objects with second class treatment for functions as in Java/Ruby.</li>
<li><strong>Multi core compatible</strong> : Should have good constructs for leveraging multiple cores eg. erlang, scala, clojure and many others.</li>
<li><strong>Type inferencing</strong> : (and I am a python programmer <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). Good type inferencing coupled with on the fly non intrusive/disruptive compilations as with say the eclipse on the fly compiler or play framework. Three cheers for Scala. One reason I prefer type inferencing to dynamic typing is the much superior performance even while maintaining brevity and removing boilerplate.</li>
<li><strong>Constructs that are natural to humans not mathematics</strong> : This is actually a sub point to Simplicity. The constructs should be consistent with the normal average non mathematically trained brains. 2 + 3 is much simpler to understand than (+ 2 3). Python rocks. Lisp / Clojure or for that matter brainfuck dont.</li>
<li><strong>Closures and code blocks</strong> : Love ruby for this.</li>
</ul>
<p><strong>Is this a pipe dream ?</strong></p>
<p>For the moment seems so. Do you know of a language which helps meet these requirements ?</p>
<p>And to be very clear (because there is a substantial risk of the same) &#8211; this is no flame bait or an opportunity to trigger language wars. It is meant to highlight two things </p>
<ol>
<li>There is no ideal language out there, and</li>
<li>When designing languages &#8211; make them simple to learn and use. ie. for a given problem statement a good language is one which requires the minimum talent or training to solve the problem</li>
</ol>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=tBGxM_aa8Uw:eSBESS6vk18:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=tBGxM_aa8Uw:eSBESS6vk18:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=tBGxM_aa8Uw:eSBESS6vk18:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=tBGxM_aa8Uw:eSBESS6vk18:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=tBGxM_aa8Uw:eSBESS6vk18:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=tBGxM_aa8Uw:eSBESS6vk18:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/tBGxM_aa8Uw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/08/my-ideal-programming-language/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/08/my-ideal-programming-language/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=my-ideal-programming-language</feedburner:origLink></item>
		<item>
		<title>Presentation : Recent trends in technology</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/B4neZOB-7uY/</link>
		<comments>http://blog.dhananjaynene.com/2010/07/presentation-recent-trends-in-technology/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 14:03:44 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[trends]]></category>

	<!-- AutoMeta Start -->
	<category>trends</category>
	<category>presentation</category>
	<category>financial</category>
	<category>conducted</category>
	<category>presentations</category>
	<category>audience</category>
	<category>dhananjay</category>
	<category>nene</category>
	<category>trends</category>
	<category>presentation</category>
	<category>financial</category>
	<category>conducted</category>
	<category>presentations</category>
	<category>audience</category>
	<category>dhananjay</category>
	<category>nene</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1012</guid>
		<description><![CDATA[This was a presentation I recently conducted to an audience of programmers / architects primarily in the financial services domain. Trends in technology View more presentations from Dhananjay Nene. No related posts.]]></description>
			<content:encoded><![CDATA[<p>This was a presentation I recently conducted to an audience of programmers / architects primarily in the financial services domain.</p>
<div style="width:625px" id="__ss_4745024"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/dnene/trends-intechnology" title="Trends in Technology">Trends in technology</a></strong><object id="__sse4745024" width="625" height="522"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=trends-in-technology-100713085442-phpapp01&#038;stripped_title=trends-intechnology" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse4745024" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=trends-in-technology-100713085442-phpapp01&#038;stripped_title=trends-intechnology" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="625" height="522"></embed></object>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/dnene">Dhananjay Nene</a>.</div>
</div>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=B4neZOB-7uY:Gi_aPXhLFkU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=B4neZOB-7uY:Gi_aPXhLFkU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=B4neZOB-7uY:Gi_aPXhLFkU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=B4neZOB-7uY:Gi_aPXhLFkU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=B4neZOB-7uY:Gi_aPXhLFkU:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=B4neZOB-7uY:Gi_aPXhLFkU:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/B4neZOB-7uY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/07/presentation-recent-trends-in-technology/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/07/presentation-recent-trends-in-technology/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=presentation-recent-trends-in-technology</feedburner:origLink></item>
		<item>
		<title>Double whammy. The state and dilemma of Indian IT</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/I2Ct8NUBwP0/</link>
		<comments>http://blog.dhananjaynene.com/2010/03/double-whammy.-the-state-and-dilemma-of-indian-it/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 18:53:21 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[management]]></category>
		<category><![CDATA[software]]></category>

	<!-- AutoMeta Start -->
	<category />
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=1005</guid>
		<description><![CDATA[Every now and then I come across a blog post which talks about outsourcing and soon enough a commentary or discussion on Indian IT and a whole host of associated parameters comes up. Soon enough some of them start attracting a number of views and comments. And more often than not the comment stream starts [...]]]></description>
			<content:encoded><![CDATA[<p>Every now and then I come across a blog post which talks about outsourcing and soon enough a commentary or discussion on Indian IT and a whole host of associated parameters comes up. Soon enough some of them start attracting a number of views and comments. And more often than not the comment stream starts attracting far more extreme views which do sometimes leave me recoiled.</p>
<p>No, I am not going to list them, link to them or comment on their content specifically. After some thought I decided that simply would shift the focus unnecessarily. Instead I thought given my reasonably long experience both in and outside India, it would be helpful offer my perspective on Indian IT within the context of global IT and Indian economy. </p>
<p><em>Indian IT and the role of exports</em></p>
<p>Indian IT (along with ITES and Gems &#038; Jewellery) is a one of the stranger segments of the Indian economy. Unlike the rest of Indian economy, it is heavily export focused. The various numbers reflecting the state of Indian IT agree on at least one factor &#8211; at least 2/3rd of its revenues are based on exports.</p>
<p>Let us first look at some of the perceptions about Indian IT that I would like to comment upon.</p>
<p><strong>You get what you pay for</strong> : In general thats a very reasonable statement. But it breaks down when you realise one Indian engineer + 1 H1B visa + 1 long flight results in tripling (at least) of remuneration without either the H1B visa or the long flight adding anything to the capability or the quality of the output of the engineer (well it could add a chip on the shoulder). Part of the difference is due to the difference in nominal exchange rates (which are driven by demand and supply of goods to/from the respective countries) and the exchange rates based on purchasing power parity. Based on purchasing power parity Indian salaries in the IT space do not underperform the rest of the world substantially. In fact when compared on purchasing power parity Indian Economy GDP more than triples and it ranks as the fourth largest economy in the world next only to the US, China and Japan.</p>
<p><strong>Indian engineers are offering their services too cheaply.</strong> : Quite to the contrary exactly the opposite is true. The Indian IT engineer is too handsomely remunerated compared to the non IT engineers in India. I believe the high salaries in Indian IT is a problem. Many Indian innovations are today happening in areas outside of IT &#8211; primarily in the areas of making products and services affordable to the millions surviving on the fringe of the poverty line. And if recent trends in automobiles and telecom sectors are indicative, India is actually proving, that it is the rest of the world which is way too expensive, by offering products and services at price points which are unfathomable elsewhere. My reading of the empirical evidence leads me to believe that Indian IT could underperform other sectors of the Indian economy in terms of both innovation and quality. And a lot of it is due to the fact that the export revenues offer cushy jobs without the really hard work it takes to compete within the Indian economy. Quite frankly this one stereotype must be deposited very quickly where it belongs. In the Trash Can. So let me repeat &#8211; Indian engineers are and Indian software is too expensive and containment in its cost growth is most urgently required. While containing salary growth might be useful, investing in ability to create high quality software upfront and eliminating the defect fixing cycles post the initial release will help bring the cost down.</p>
<p><strong>Indian IT offers poor quality software</strong> (The alternative version is outsourcing leads to drop in quality) : This is too hard a statement to comment upon, given its utter and gross generalisation. I am not aware of specific quality benchmarks which could be used to assert or deny such claims, though there is a fair amount of empirical evidence which could be used to either assert or deny these claims. India like any other country has a range of software quality in different companies and products which span the entire spectrum from superb to utter crap. I tend to agree with the statement that in many cases Indian software output does leave a lot to be desired in terms of quality. I also believe that there is a curious dynamic at play here. It is well known that in software one can demand and expect any two of three parameters to be fulfilled &#8211; viz. Cost, Time and Quality. Any efforts to increase quality can in some contexts run into the business issue of the customer clearly prioritising cost and time to market. And remember two thirds of the revenues (and presumably the customers) of Indian IT are from overseas. I have often struggled hard on the quality aspects, and have generally found that it requires a very strong support not just from the engineers but from the business stakeholders to offer sustained high quality. </p>
<p><strong>Indian engineers are not as skilled / Indian engineers are far superior to the rest of the world</strong> : This is an interesting stereotype which is obviously wrong at either of the two extremes at which it is observed. Some believe the Indian engineers are extremely competent and productive but fail to realise that these engineers are from the extreme top end of a very competitive educational system. Bring down the comparison to some reasonable way of comparing an average Indian and Non Indian IT programmer and perhaps the comparison may not be so rosy for India. I think India does need to work much harder to strengthen its capabilities of programmers at the middle and lower ends. And sometimes I blame the fact that too many projects being transferred to India has resulted into so much demand for programmers that a programmer with a 10 percentile performance can still make a wonderful living by just changing his jobs every two years. This needs to change. But I am afraid as long as India continues to bill the rest of the world by the hour and not by capability and quality, this shall continue to be an uphill battle even as we shall continue to see islands of excellence. </p>
<p><strong>Double whammy</strong></p>
<p>The double whammy I refer to in the title of this post stems from the fact that due to heavy reliance on exports, Indian IT has been substantially based on the priorities dictated by her customers. Thus Indian IT is largely today what its customers asked it to be. And most of the customers are non Indian. The double whammy is the fact that Indian IT gets criticised for becoming exactly what its customers asked it to be &#8211; fast, low cost and high quality so long as the high quality doesn&#8217;t interfere with the fast or the low cost <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . To be fair I am aware of the same criteria getting applied within many non Indian IT companies as well &#8211; so its not an Indian innovation. To be fair I am also aware of some situations where the lack of focus on quality is not driven by customer prioritisation. Is there a way out of the double whammy. Frankly I can&#8217;t see one easily. Yet this post would perhaps go some way in enriching the reader&#8217;s perspective on some of these factors.</p>
<p><strong>The role of the population</strong></p>
<p>There is one aspect about India which separates her from many other IT exporting countries. Her population. Not is it only really large (the second largest in the world), but it is growing fast and expected to continuously grow younger over the next two decades (dream demographics for an economist). Which means India stands unique in her ability to deploy masses. Which also means the problems which are easier to solve by deploying masses are more likely to find their way to the Indian shores. Combined with a high growth rate it also contributes to most Indian programmers getting promoted to management ranks (whatever that means) fairly soon. As we shall see in the next section this is an important factor in the Indian context.</p>
<p><strong>Improving capability and quality</strong> </p>
<p>Independent of the validity of stereotypes which I questioned above I think it is a dead certainty that Indian IT can focus on improving both its capability and quality. It is not infrequent for me to feel demotivated after meeting some college students or fresh graduates and realising their priorities are really driven around what is the quickest way to make maximum money. This leads to unhealthy focus on building skills with high resume value. (Yeah that may sound funny to some of you, but its not uncommon). And given the high growth as I referred to in the earlier section &#8211; the role model for IT is &#8211; start as a programmer, change jobs every 2-3 years, become a team lead in 3 years, a manager in 6. And if you are particularly technically inclined you can become an architect guiding many projects and helping support many pre-sales efforts. What I haven&#8217;t seen Indian IT getting criticised for frequently enough, is the fact that so few of her members contribute to open source. While dzone and reddit may attract a large number of readers from India, a disproportionately small proportion of the people writing the posts stay in India. And most good programmers have moved on to becoming a Tech Lead or a Project Manager driving the average sustained technology experience lower and lower. So much for the &#8220;IT superpower&#8221; marketing that the hype manufacturing machinery creates internally. In a recent meeting with around 20 plus people in the room, I was one of the only 2-3 persons who believed India is not an IT superpower.</p>
<p><strong>Change</strong></p>
<p>I would like this to change. I would like this to change substantially. But I do not see the economic incentives in place for that to happen. Yet. However there is this strong feeling that something will indeed happen to make things change for the better. This is clearly something Indian IT will need to grapple with in the months and years to come. However there are at least a few factors which will lend themselves positively towards strengthening Indian IT.</p>
<p><em>Agile</em>. Movement to agile requires a continuous focus on quality that cannot be wished away as easily. Projects that genuinely adopt agile methodologies will be implicitly driven toward being able to offer higher and sustained high quality. </p>
<p><em>Saas</em>. As more software development shifts from intra enterprise development (where it is a little easier to contain impacts of poor quality) into Saas, there will be implicit pressures from the customers on the quality front. Another positive influence of Saas is that given the higher sharing of software across a much larger user base, the demand for number of developers would come down. Even as it may influence the demand for Indian IT itself negatively, I think it would help drive Indian IT into focusing more on capability than deploying masses.</p>
<p><em>Internal Growth</em>. While much of the historic growth of Indian IT came from outsourcing, I anticipate the Indian industry to start driving its growth even more soon (given the really high growth engine it finds itself in). In such scenarios, the portfolio of software assignments will include a higher number of strategic and critical projects at extremely challenging cost parameters. This portfolio readjustment will help influence the quality positively. </p>
<p>I&#8217;ve attempted to highlight that Indian IT as exists today is (partially) a function of her customer&#8217;s expectations. And while there are some unfair stereotypes about it, there are clearly some things it can clearly improve upon. It is with some trepidation I write this since attempting to deal with perceptions in a generalised / stereotyped scenarios can be quite risky. So allow me to end with the disclaimer. This is a documentation of my understanding &#8211; YMMV.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=I2Ct8NUBwP0:GoI3FDRv9D4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=I2Ct8NUBwP0:GoI3FDRv9D4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=I2Ct8NUBwP0:GoI3FDRv9D4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=I2Ct8NUBwP0:GoI3FDRv9D4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=I2Ct8NUBwP0:GoI3FDRv9D4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=I2Ct8NUBwP0:GoI3FDRv9D4:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/I2Ct8NUBwP0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/03/double-whammy.-the-state-and-dilemma-of-indian-it/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/03/double-whammy.-the-state-and-dilemma-of-indian-it/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=double-whammy.-the-state-and-dilemma-of-indian-it</feedburner:origLink></item>
		<item>
		<title>Functional Programming with Python – Part 2 – Useful python constructs</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/AFNcTOyuJog/</link>
		<comments>http://blog.dhananjaynene.com/2010/03/functional-programming-with-python-%e2%80%93-part-2-useful-python-constructs/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 16:48:05 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[functional programming]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[sequences]]></category>

	<!-- AutoMeta Start -->
	<category>onetofive</category>
	<category>onetofive</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=983</guid>
		<description><![CDATA[In Functional Programming with Python – Part 1, I focused on providing an overview. In this post I shall focus on the core python language constructs supporting functional programming. If you are experienced pythonista, you may choose to skip this post (and wait for the next post in this series ) Sequences in python are [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://blog.dhananjaynene.com/2010/02/functional-programming-with-python-part-1/">Functional Programming with Python – Part 1</a>, I focused on providing an overview. In this post I shall focus on the core python language constructs supporting functional programming. If you are experienced pythonista, you may choose to skip this post (and wait for the next post in this series <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p><strong>Sequences in python are not immutable :</strong></p>
<p>When using sequences in python the thing to be noted is that sequences are not immutable. This provides you with the following options.</p>
<p>a) Use immutable sequence types : This is only possible by defining different types for sequences than the ones built into the language.<br />
b) Ignore all methods on the sequences which modify them<br />
c) Waive functional programming tenet of immutability </p>
<p>My preferred option when explicitly focusing on writing functional code is to use b) </p>
<p><strong>Sequence types in python</strong></p>
<p>The most commonly used sequence types in python are :</p>
<ul>
<li>Tuple : Immutable, Ordered, Indexed collection represented as <em>(val1, val2)</em></li>
<li>List : Ordered collection represented as <em>[val1, val2]</em></li>
<li>Dictionary : A key indexed collection represented as <em>{ key1: val1, key2 : val2 }</em></li>
<li>Set : An unordered collection allowing no duplicates. Represented as <em>set([val1,val2])</em></li>
<li>str and unicode : While primarily meant to serv as ascii and unicode strings, these data structures also act as sequences of characters.<em>Represented as &#8220;abcd&#8221; or &#8216;abcd&#8217;</em></li>
</ul>
<p>Of the above only tuples are immutable.</p>
<p>There are other sequences used less often as well. An example is <em>frozenset</em> which is an immutable set. </p>
<p><strong>Simple iteration</strong><br />
The <em>for</em> construct allows you to loop through a sequence. eg.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">one_to_five <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: black;">&#93;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> num <span style="color: #ff7700;font-weight:bold;">in</span> one_to_five : <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> num</div></td></tr></tbody></table></div>
<p><strong>Iterators on dictionaries</strong></p>
<p>Unlike tuples, lists and sets where iterators essentially traverse through the sequence constituents, there are a number of different iterators on dictionaries. These are :</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">d <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #ff4500;">1</span>:<span style="color: #483d8b;">&quot;One&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span>: <span style="color: #483d8b;">&quot;Two&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span>:<span style="color: #483d8b;">&quot;Three&quot;</span><span style="color: black;">&#125;</span><br />
<span style="color: #808080; font-style: italic;"># keys</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> val <span style="color: #ff7700;font-weight:bold;">in</span> d : <span style="color: #ff7700;font-weight:bold;">print</span> val<br />
<span style="color: #808080; font-style: italic;"># an alternative for keys</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> val <span style="color: #ff7700;font-weight:bold;">in</span> d.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> : <span style="color: #ff7700;font-weight:bold;">print</span> val<br />
<span style="color: #808080; font-style: italic;"># values</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> val <span style="color: #ff7700;font-weight:bold;">in</span> d.<span style="color: black;">values</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> : <span style="color: #ff7700;font-weight:bold;">print</span> val<br />
<span style="color: #808080; font-style: italic;"># key, value tuples</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> key<span style="color: #66cc66;">,</span>val <span style="color: #ff7700;font-weight:bold;">in</span> d.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> : <span style="color: #ff7700;font-weight:bold;">print</span> key<span style="color: #66cc66;">,</span> val</div></td></tr></tbody></table></div>
<p><strong>Slices</strong></p>
<p>Slices allow creation of a subset on a sequence. They take the syntax <em>[start:stop:step]</em> with the caveat that a negative value for start or stop indicates an index from the end of the sequence measured backwards, whereas a negative step indicates a step in the reverse direction. The following should quickly indicate the use of slices</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">seq<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">6</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">7</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #808080; font-style: italic;">#first 3</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> seq<span style="color: black;">&#91;</span>:<span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><br />
<span style="color: #808080; font-style: italic;"># last 3</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> seq<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">3</span>:<span style="color: black;">&#93;</span><br />
<span style="color: #808080; font-style: italic;"># 2nd to second last</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> seq<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><br />
<span style="color: #808080; font-style: italic;"># reverse the sequence</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> seq<span style="color: black;">&#91;</span>::-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span></div></td></tr></tbody></table></div>
<p><strong>The iterator protocol</strong><br />
Since python is an object oriented language as well, it provides strong support for allowing iteration over an object internals. Any object in python can behave like a sequence by providing the following :</p>
<p>a. It must implement the <em>__iter__()</em> method which in turn supports the iterator protocol<br />
b. The iterator protocol requires the returned object, an iterator,  to support the following ie. an <em>__iter__() </em>method returning self. and a <em>next()</em> method which returns the next element in the sequence, or raise a StopIteration in case the end of iteration is reached.</p>
<p><em>I&#8217;ve tested iterators which do not themselves have an __iter__() method and it still works, but I still do not give in to the temptation of not defining the next() method alone since that would be inconsistent with the documented python specifications </em></p>
<p>Let us examine a simple class indicating a range. Note that this is just for demonstration since python itself has better constructs for a range.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># An iterator object to sequentially offer the next number</span><br />
<span style="color: #808080; font-style: italic;"># in a sequence. Raises StopIteration on reaching the end</span><br />
<span style="color: #ff7700;font-weight:bold;">class</span> RangeIterator<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span>begin<span style="color: #66cc66;">,</span>end<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>._next <span style="color: #66cc66;">=</span> begin - <span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">end</span> <span style="color: #66cc66;">=</span> end<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> next<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>._next +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>._next <span style="color: #66cc66;">&lt;</span> <span style="color: #008000;">self</span>.<span style="color: black;">end</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._next<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">StopIteration</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #808080; font-style: italic;"># A class which allows sequential iteration over a range of</span><br />
<span style="color: #808080; font-style: italic;"># values (begin inclusive, end exclusive)</span><br />
<span style="color: #ff7700;font-weight:bold;">class</span> Range<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span>begin<span style="color: #66cc66;">,</span>end<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">begin</span> <span style="color: #66cc66;">=</span> begin<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">end</span> <span style="color: #66cc66;">=</span> end<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__iter__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> RangeIterator<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">begin</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span>.<span style="color: black;">end</span><span style="color: black;">&#41;</span><br />
<br />
oneToFive <span style="color: #66cc66;">=</span> Range<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>In the above example, <em>__iter__()</em> on Range returns an instance of a RangeIterator.</p>
<p>The way this capability is used is as follows :</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">for</span> number <span style="color: #ff7700;font-weight:bold;">in</span> oneToFive :<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Next number is : %s'</span> % number<br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Is 2 in oneToFive'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span> <span style="color: #ff7700;font-weight:bold;">in</span> oneToFive<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Is 9 in oneToFive'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">9</span> <span style="color: #ff7700;font-weight:bold;">in</span> oneToFive</div></td></tr></tbody></table></div>
<p>The output you get with it is :</p>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Next number is : 1<br />
Next number is : 2<br />
Next number is : 3<br />
Next number is : 4<br />
Is 2 in oneToFive True<br />
Is 9 in oneToFive False</div></td></tr></tbody></table></div>
<p><strong>Generators</strong></p>
<p>In the above situation, the state necessary for the iteration (ie.begin and end attributes) need to be stored. This was stored as a class member. Python also provides a function based construct called a generator. In case of a generator, the function should just do a <em>yield</em> instead of a return. Python implicitly provides a next() method which resumes where the last yield left off and implicitly raises a StopIteration when the function completes. So representing the above class as a function,</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> my_range<span style="color: black;">&#40;</span>begin<span style="color: #66cc66;">,</span> end<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; current <span style="color: #66cc66;">=</span> begin<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> current <span style="color: #66cc66;">&lt;</span> end :<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">yield</span> current<br />
&nbsp; &nbsp; &nbsp; &nbsp; current +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #ff7700;font-weight:bold;">for</span> number <span style="color: #ff7700;font-weight:bold;">in</span> my_range<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span> :<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Next number is : %s'</span> % number<br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Is 2 in oneToFive'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span> <span style="color: #ff7700;font-weight:bold;">in</span> my_range<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Is 9 in oneToFive'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">9</span> <span style="color: #ff7700;font-weight:bold;">in</span> my_range<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>I do not document the results since these are identical to the earlier code using a RangeIterator.</p>
<p><em>Note: I used my_range() and not range() since there already exists another range() already provided by python</em></p>
<p>An interesting point to realise is that in both the above situations, the next element to be returned in the sequence was being computed dynamically. To put it in the terminology better consistent with functional programming, it was being lazily evaluated. While python has no mechanism of lazy evaluation of functions, the ability of functions or objects to lazily evaluate the return values are sufficiently adequate to get the benefits of lazy evaluation at least from the perspective of cpu utilisation only on demand, and minimal memory utilisation. </p>
<p><strong>List comprehensions</strong></p>
<p>List comprehensions are one of the most powerful functional programming constructs in python. To quote from python documentation (even as I leave out a very important part of the full quote .. to be covered later), </p>
<blockquote><p>Each list comprehension consists of an expression followed by a for clause, then zero or more for or if clauses. The result will be a list resulting from evaluating the expression in the context of the for and if clauses which follow it. If the expression would evaluate to a tuple, it must be parenthesized.</p></blockquote>
<p>A sample list comprehension is one which returns a sequence of even numbers between 0 and 9 :</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># A list comprehension that returns even numbers between 0 and 9</span><br />
even_comprehension <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>num <span style="color: #ff7700;font-weight:bold;">for</span> num <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> num % <span style="color: #ff4500;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">type</span><span style="color: black;">&#40;</span>even_comprehension<span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span>even_comprehension<span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>The output one gets on running the code above is</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">type</span> <span style="color: #483d8b;">'generator'</span><br />
<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">4</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">6</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">8</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Note that the list comprehension returns a generator which then returns a sequence containing 0, 2, 4, 6 and 8.</p>
<p>The for and if statements can be deeply nested.</p>
<p><strong>lambda</strong></p>
<p>Lambdas are anonymous functions with a constraint. Their body can only be a single expression which is also the return value of the function. I will demonstrate their usage in the next section.</p>
<p><strong>map, filter and reduce</strong></p>
<p>Three of the functional programming constructs which probably have aroused substantial discussions within the python community are map, filter and reduce.</p>
<p><em>map</em> takes a sequence, applies a function of each of its value and returns a sequence of the result of the function. Thus if one were to use map with a function which computes the square on a sequence, the result would be a sequence of the squares. Thus</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> square<span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> num * num<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span><span style="color: #008000;">map</span><span style="color: black;">&#40;</span>square<span style="color: #66cc66;">,</span><span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>results into</p>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">(0, 1, 4, 9, 16)</div></td></tr></tbody></table></div>
<p>I mentioned earlier I will demonstrate usage of a lambda. In this case I could use a lambda by defining the square function anonymously in place as follows :</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span><span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> num : num * num<span style="color: #66cc66;">,</span><span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p><em>filter</em> takes a predicate and returns only the elements in the sequence for whom the predicate evaluates to true.</p>
<p>Thus</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x : x % <span style="color: #ff4500;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>results in the following output</p>
<div class="codecolorer-container text dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[0, 2, 4]</div></td></tr></tbody></table></div>
<p>Finally the most controversial of them all &#8211; <em>reduce</em>. Starting with an initial value, reduce reduces the sequence down to a single value by applying a function on each of the elements in the sequence along with the current manifestation of the reduced value. Thus if I wanted to compute the sum of squares of numbers 0 through 4, I could use the following</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">reduce</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> reduced<span style="color: #66cc66;">,</span>num : reduced + <span style="color: black;">&#40;</span>num * num<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>In the above example, 0 as the right most argument is the initial value. range(5) is the sequence of numbers from 0 thru 4. Finally the anonymous lambda takes two parameters &#8211; the first is always the current value of the reduced value (or initial value in case it is being invoked for the very first time) and the second parameter is the element in the sequence. The return value of the function is the value which will get passed to the subsequent invocation of the reduce function with the next element in the sequence as the new reduced value. The reduced value as returned finally by the function is then the returned value from <em>reduce</em></p>
<p>The functional programming folks are likely to find this an extremely natural expression. Yet reduce resulted in a substantial debate within the python community. With the result that reduce is now being <em>removed</em> from python 3.0. (Strictly speaking it is being removed from python core but will be just an import statement away as a part of the functools package). See <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=98196">The fate of reduce() in Python 3000</a>. Why so controversial ? Simply because the usage of map, filter, reduce above could be rewritten as</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#map</span><br />
seq <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> num <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span> :<br />
&nbsp; &nbsp; seq <span style="color: #66cc66;">=</span> seq + <span style="color: black;">&#91;</span>num * num<span style="color: black;">&#93;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> seq<br />
<br />
<span style="color: #808080; font-style: italic;">#filter</span><br />
seq <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> num <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span> :<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> num % <span style="color: #ff4500;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; seq <span style="color: #66cc66;">=</span> seq + <span style="color: black;">&#91;</span>num<span style="color: black;">&#93;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> seq<br />
<br />
<span style="color: #808080; font-style: italic;">#reduce</span><br />
total <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> num <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span> : <br />
&nbsp; &nbsp; total <span style="color: #66cc66;">=</span> total + <span style="color: black;">&#40;</span>num * num<span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> total</div></td></tr></tbody></table></div>
<p>Just look at the two blocks of code and figure out which is easier to read (especially look at reduce). One of the areas where a large number of pythonistas and lispists are likely to disagree is the tradeoffs between brevity and easy readability. Python code is often english like (well, at least to the extent that a programming language can be) and some pythonistas do not like the terse syntax of lisp thats hard to follow. </p>
<p>I earlier mentioned that I left out a part of the description of list comprehensions from python documentation. Here&#8217;s that part of the quote.</p>
<blockquote><p>List comprehensions provide a concise way to create lists without resorting to use of map(), filter() and/or lambda. The resulting list definition tends often to be clearer than lists built using those constructs. </p></blockquote>
<p>Having said that I do believe many including myself will continue to use map, filter, reduce</p>
<p>Other helpful functions in python core that are helpful for functional programming are :</p>
<ul>
<li><em>all</em> : Returns True if all elements in a sequence are true</li>
<li><em>any</em> : Returns True if any element in a sequence is true</li>
<li><em>enumerate</em> : Returns a sequence containing tuples of element index and element</li>
<li><em>max</em> : Returns the maximum value in a sequence</li>
<li><em>min</em> : Returns the minimum value in a sequence</li>
<li><em>range</em> : Return a sequence for given start, end and step values</li>
<li><em>sorted</em> : Returns a sorted form of the sequence. It is possible to specify comparator functions, or key value for sorting, or change direction of sort</li>
<li><em>xrange</em> : Same as range except it generates the next sequence element only on demand (lazy evaluation) thus helping conserve memory or work with infinite sequences.</li>
</ul>
<p>We&#8217;ve seen many of the constructs that are typically useful for functional programming. I left out one big part &#8211; the <em>itertools</em> package. This is not a part of python core (its a package which is available with a default python installation). Its a large library and substantially helps functional programming. That along with some more sample python programs shall be the focus of my next blog post in the series. At this point in time I anticipate at least a few more parts after that to focus on a) Immutability b) Concurrency and c) Sample usage.</p>
<p>Hope you found this useful and keep the feedback coming so that I can factor it into the subsequent posts.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=AFNcTOyuJog:n1wtSNs51PA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=AFNcTOyuJog:n1wtSNs51PA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=AFNcTOyuJog:n1wtSNs51PA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=AFNcTOyuJog:n1wtSNs51PA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=AFNcTOyuJog:n1wtSNs51PA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=AFNcTOyuJog:n1wtSNs51PA:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/AFNcTOyuJog" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/03/functional-programming-with-python-%e2%80%93-part-2-useful-python-constructs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/03/functional-programming-with-python-%e2%80%93-part-2-useful-python-constructs/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=functional-programming-with-python-%25e2%2580%2593-part-2-useful-python-constructs</feedburner:origLink></item>
		<item>
		<title>Functional Programming with Python – Part 1</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/39xvqqNOfC4/</link>
		<comments>http://blog.dhananjaynene.com/2010/02/functional-programming-with-python-part-1/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 18:05:51 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[functional programming]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[software]]></category>

	<!-- AutoMeta Start -->
	<category />
	<category />
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=970</guid>
		<description><![CDATA[Lately there has been a substantial increase in interest and activity in Functional Programming. Functional Programming is sufficiently different from the conventional mainstream programming style called Imperative Programming to warrant some discussion on what it is, before we delve into the specifics of how it can be used in Python. What is Functional Programming? To [...]]]></description>
			<content:encoded><![CDATA[<p>Lately there has been a substantial increase in interest and activity in <a href="http://en.wikipedia.org/wiki/Functional_programming">Functional Programming</a>. Functional Programming is sufficiently different from the conventional mainstream programming style called <a href="http://en.wikipedia.org/wiki/Imperative_programming">Imperative Programming</a> to warrant some discussion on what it is, before we delve into the specifics of how it can be used in Python.</p>
<p><strong>What is Functional Programming?</strong></p>
<p>To quote from Wikipedia,</p>
<blockquote><p>In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state.</p></blockquote>
<p>For beginners, one of the most fluent starter pages I would recommend for the history and specifics of functional programming is <a href="http://www.defmacro.org/ramblings/fp.html">Functional Programming For The Rest of Us</a>. This is a must read article which provides the reader with a good overview without getting too much into the nitty gritties of functional programming.</p>
<p>Since a detailed discussion on functional programming (henceforth referred to FP) is beyond the scope of this post, I will just briefly summarise the most critical elements of FP.</p>
<ul>
<li><strong>Functions as the basic building blocks :</strong> Unsurprisingly FP requires the construction and usage of functions as the basic building units. In the simplest terms &#8220;<em>int add(int x, int y) { return x + y; }</em>&#8221; is a simple addition function written in &#8216;C&#8217;. It takes two parameters x and y, adds them, and returns the result. This is a rather obvious and simple case but I stated it since I would like to refer back to it subsequently in this post.</li>
<li><strong>Functional Programming prefers functions without side effects : </strong> The <em>add</em> function above is a good example of a function without side effects. A function is said to be without side effects if the only changes it makes are those that are manifested in the return values. In other words such a function cannot change any global variables, write to the console, update the database etc. A fairly related term is <em>referential transparency</em>. A function is said to be referentially transparent if its invocation can be substituted by the return value in a program without impacting the program in any other way.</li>
<li><strong>Immutability </strong>: Pure functional programming often requires you to deal with immutable data structures. Thus the value of any variable is not open to modification (Thus they are called values and not variables). This aspect complements the functions without side effects. Thus the way most changes to state are implemented are not by modifying an object in place (which is how imperative programming deals with it) but by cloning the data structure with some of the values getting modified and the modified data structure being returned by the function. Java programmers are aware of the immutability of the String instances wherein any modifications to the string result in a new String instance being created. Imagine the same happening to all the datatypes across the program.</li>
</ul>
<p><strong>Benefits of Functional Programming :</strong></p>
<p>Some of the nice benefits (I am tempted to say side effects) of functional programming are :</p>
<ul>
<li><strong>Superior ability to deal with concurrency (multi threading) : </strong>Threaded programs are nasty to write. And nastier to debug. In an imperative environment, you not only have to deal with data structures being modified in place by some other parts of the program, in a threaded environment such modifications can happen using peer threads, even as your current thread whose logic you are focusing on is attempting to exercise that logic. Its an extremely unpredictable environment which has resulted in a number of how-to&#8217;s for safe threaded programming using constructs such as locks, mutexes etc. Functional programming deals with the issue far more elegantly. Instead of controlling and managing unpredictability, it takes it out completely. Because a data structure once constructed will not be modified and because the source of the modifications can be clearly located to the function which instantiated the datastructure, the unpredictability of data changing right under you is gone. This can be a little expensive to manage and FP does sometimes come up with some compromises (or cool features depending on how you view it) such as Software Transactional Memory but a discussion on that is completely beyond the scope of this post.</li>
<li><strong>Easier testing and debugging : </strong>Because modifications to data are contained and because a function communicates with the context outside it only via its return values, testing and debugging become far easier. You essentially need to focus on testing each function individually. Similarly during debugging you need to be able to quickly locate the function likely to have the problem, after which you can easily focus on the function to be able to quickly resolve the issue. Mocking out functions can also help testing each function in isolation. In general because of fewer side effects, testing under functional programming is often a lot easier, and the importance of having to do &#8220;integration&#8221; testing and &#8220;module&#8221; testing is lesser since testing functions in isolation is likely to identify most issues, far more than in typical imperative programming.</li>
</ul>
<p><strong>Why Python?</strong></p>
<p>Python is not the best functional programming language. But it was not meant to be. Python is a multi paradigm language. Want to write good old &#8216;C&#8217; style procedural code? Python will do it for you. C++/Java style object oriented code? Python is at your service as well. Functional Programming ? As this series of posts is about to demonstrate &#8211; Python can do a decent job at it as well. Python is probably the most productive language I have worked with (across a variety of different types of programming requirements). Add to that the fact that python is a language thats extremely easy to learn, suffers from excellent readability, has fairly good web frameworks such as <a href="http://www.djangoproject.com/">django</a>, has excellent mathematical and statistical libraries such as <a href="http://numpy.scipy.org/">numpy</a>, and cool network oriented frameworks such as <a href="http://twistedmatrix.com/trac/">twisted</a>. Python may not be the right choice if you want to write 100% FP. But if you want to learn more of FP or use FP techniques along with other paradigms <em>Python&#8217;s capabilities are screaming to be heard<strong>.</strong></em></p>
<p><strong>Sample Program :</strong></p>
<p>I debated whether I should introduce various elements of functional programming using python in detail and then put it all together in a sample program all in future blog posts of this series, or whether I should start with a sample program which cover various aspects of function programming in this post and then explain various aspects in much more detail in future posts. For better or for worse, I have chosen the latter option. That means I shall be explaining one sample program and shall leave it to future posts in this series to get into greater details.</p>
<p>The sample program I have chosen is that of a simple calculator. A typical calculator supports simple unary or binary mathematical operators and performs floating point operations. Without much ado we now get into the sample program.</p>
<p><em>Immutable Data :</em></p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">collections</span> <span style="color: #ff7700;font-weight:bold;">import</span> namedtuple<br />
<br />
Context <span style="color: #66cc66;">=</span> namedtuple<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Context'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'stack, current, op'</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> default_context<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> Context<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">0.0</span><span style="color: #66cc66;">,</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Python is not particularly strong at immutable data. However one of the data structures, a tuple is immutable. A <em>namedtuple</em> is another data structure which supports both tuple like access through indices or through named elements in the tuple. For the calculator I shall need a <em>Context</em> which contains a <em>stack</em> for storing any incomplete operations, an attribute <em>current</em> reflecting the current value being shown on the screen and an <em>op</em> which might reflect a pending operation which is typically required for binary operators where the second value still needs to be provided. While namedtuple is a reasonable construct for simple tuple like objects, it would be helpful to have immutable objects as well &#8211; but thats to be covered in a future post.</p>
<p><em>Simple Functions</em></p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> add<span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span>y<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> x + y<br />
<span style="color: #ff7700;font-weight:bold;">def</span> sub<span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span>y<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> x - y<br />
<span style="color: #ff7700;font-weight:bold;">def</span> mult<span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span>y<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> x * y<br />
<span style="color: #ff7700;font-weight:bold;">def</span> div<span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span>y<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> x/ y<br />
<span style="color: #ff7700;font-weight:bold;">def</span> reverse_sign<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> -<span style="color: #ff4500;">1</span> * x<br />
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #008000;">pow</span><span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span>y<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> x ** y</div></td></tr></tbody></table></div>
<p>There&#8217;s not much to describe here. The functions should be self explanatory. For purpose of emphasis I would like to note that in the above code, &#8220;add&#8221; is now an entry in the namespace which is a reference to a function. This reference can be passed around, assigned to other entries. Thus the code below should work (though it does not form a part of the calculator program). This is to demonstrate how python treats attributes and functions virtually identically consistent with the <a href="http://en.wikipedia.org/wiki/Uniform_access_principle">Uniform access principle</a>.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">otheradd <span style="color: #66cc66;">=</span> add<br />
add <span style="color: #66cc66;">=</span> sub<br />
<span style="color: #ff7700;font-weight:bold;">assert</span> otheradd<span style="color: black;">&#40;</span><span style="color: #ff4500;">7</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">10</span><br />
<span style="color: #ff7700;font-weight:bold;">assert</span> add<span style="color: black;">&#40;</span><span style="color: #ff4500;">7</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">4</span></div></td></tr></tbody></table></div>
<p><em>Currying</em><br />
<a href="http://en.wikipedia.org/wiki/Currying">Currying</a> is a treatment afforded in functional programming which allows a function of n parameters to be treated as a sequence of n sequential functions each of one parameter.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> functools <span style="color: #ff7700;font-weight:bold;">import</span> partial<br />
<br />
square <span style="color: #66cc66;">=</span> partial<span style="color: black;">&#40;</span><span style="color: #008000;">pow</span><span style="color: #66cc66;">,</span>y<span style="color: #66cc66;">=</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Here <em>partial</em> is a function reference. <em>square</em> now refers to another function with its y parameter value being anchored to 2</p>
<p><em>Invoking functions dynamically</em></p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">unary_functions <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'!'</span> : reverse_sign<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'@'</span> : square <span style="color: black;">&#125;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> handle_unary_op<span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>x<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> ctx._replace<span style="color: black;">&#40;</span>current <span style="color: #66cc66;">=</span> unary_functions<span style="color: black;">&#91;</span>x<span style="color: black;">&#93;</span><span style="color: black;">&#40;</span>ctx.<span style="color: black;">current</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> op <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span><span style="color: black;">&#41;</span><br />
<br />
binary_functions <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'+'</span> : add<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'-'</span> : sub<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'*'</span> : mult<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'/'</span> : div<span style="color: black;">&#125;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> handle_binary_op<span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>x<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> ctx._replace<span style="color: black;">&#40;</span>op <span style="color: #66cc66;">=</span> binary_functions<span style="color: black;">&#91;</span>x<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> handle_float<span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>x<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> ctx.<span style="color: black;">op</span> : <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> ctx._replace<span style="color: black;">&#40;</span>current <span style="color: #66cc66;">=</span> x<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span> : <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> ctx._replace<span style="color: black;">&#40;</span>current <span style="color: #66cc66;">=</span> ctx.<span style="color: black;">op</span><span style="color: black;">&#40;</span>ctx.<span style="color: black;">current</span><span style="color: #66cc66;">,</span>x<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> op <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Note that I created a unary_functions dict (or dictionary or hashmap) where the key is the character which represents the function and the value is the reference to the function.</p>
<p>Also note that in the <em>handle_unary_op</em>function, I invoke <em>ctx._replace</em> method. On a named tuple it creates another tuple based on the existing namedtuple data, but with some of the values modified as specified in the keyword paramters passed to <em>_replace</em>. After looking up the appropriate unary function ie. <em>unary_functions[x]</em>, I also invoke it on the current value ie. <em>unary_functions[x](ctx.current)</em>. I also defined another dict for binary operators. The <em>handle_binary_op</em> method reflects how the op in the context is set to the appropriate binary function that should be triggered after the subsequent value is known.</p>
<p>Finally the <em>handle_float</em> function either sets the current value to the incoming value or in case the current operator is already set it applies the binary operator to the current value and the incoming value and replaces <em>current</em> with the computed value.</p>
<p><em>Additional Code</em><br />
When I wrote the calculator program, I wrote the functionality to introduce braces. However that functionality is not particularly important in this explanation. So it is being listed here for completeness.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> start_brace<span style="color: black;">&#40;</span>ctx<span style="color: black;">&#41;</span>: <br />
&nbsp; &nbsp; newstack <span style="color: #66cc66;">=</span> ctx.<span style="color: black;">stack</span><br />
&nbsp; &nbsp; newstack.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>ctx.<span style="color: black;">current</span><span style="color: #66cc66;">,</span>ctx.<span style="color: black;">op</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> ctx._replace<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stack <span style="color: #66cc66;">=</span> newstack<span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0.0</span><span style="color: #66cc66;">,</span> op <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> end_brace<span style="color: black;">&#40;</span>ctx<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; stack <span style="color: #66cc66;">=</span> ctx.<span style="color: black;">stack</span><br />
&nbsp; &nbsp; current <span style="color: #66cc66;">=</span> ctx.<span style="color: black;">current</span><br />
&nbsp; &nbsp; oldcurrent<span style="color: #66cc66;">,</span> oldop <span style="color: #66cc66;">=</span> stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; oldctx <span style="color: #66cc66;">=</span> Context<span style="color: black;">&#40;</span>stack<span style="color: #66cc66;">,</span>oldcurrent<span style="color: #66cc66;">,</span>oldop<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> process_key<span style="color: black;">&#40;</span>oldctx<span style="color: #66cc66;">,</span>current<span style="color: black;">&#41;</span><br />
<br />
tokens <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span> <span style="color: #483d8b;">'('</span>: start_brace<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">')'</span> : end_brace<span style="color: black;">&#125;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> handle_tokens<span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>x<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> tokens<span style="color: black;">&#91;</span>x<span style="color: black;">&#93;</span><span style="color: black;">&#40;</span>ctx<span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p><em>Processing one key</em><br />
I must confess I started off using key to represent the keystrokes, but along the way the key can also represent a complete floating point number (not just a single keystroke). Thus the key parameter can refer to a single character operator or a sequence of characters representing a floating point number</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">function_groups <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span>unary_functions.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> : handle_unary_op<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span>binary_functions.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> : handle_binary_op<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span>tokens.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> : handle_tokens<br />
<span style="color: black;">&#125;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> process_key<span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>key<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">types</span>.<span style="color: black;">FloatType</span><span style="color: #66cc66;">,</span><span style="color: #dc143c;">types</span>.<span style="color: black;">IntType</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">types</span>.<span style="color: black;">LongType</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> handle_float<span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>key<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">types</span>.<span style="color: black;">StringType</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> function_class <span style="color: #ff7700;font-weight:bold;">in</span> function_groups :<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> key <span style="color: #ff7700;font-weight:bold;">in</span> function_class : <span style="color: #ff7700;font-weight:bold;">return</span> function_groups<span style="color: black;">&#91;</span>function_class<span style="color: black;">&#93;</span><span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>key<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> ctx</div></td></tr></tbody></table></div>
<p>In this case I set up a dictionary where the key is a tuple of all the keys representing a particular class of a function. Note that the <em>.keys()</em> method is a method which returns a list of all the keys in a dictionary. However since list is mutable, it cannot get used as a key into the overall hashmap, hence I convert it into a tuple.</p>
<p>The <em>process_key</em> function takes the incoming key, passes it <em>handle_float</em> if it is a number, or treats it as an operator. If it is the latter it searches for it in all the keys of each operator groups, and if it finds a match, it locates the corresponding handler function from the map and invokes it. Finally in case no match is found it ignores the key.</p>
<p><em>Processing a sequence of keys</em></p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> process_keys<span style="color: black;">&#40;</span>keys<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">reduce</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> ctx<span style="color: #66cc66;">,</span>key : process_key<span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>key<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> keys<span style="color: #66cc66;">,</span> default_context<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Here you see a <em>reduce</em> function being invoked. This belongs to the family of <em>map</em> and <em>filter</em> functions which are used extensively in functional programming.  I shall attempt to briefly explain it here, but this family of functions in addition to a number of others will again be dealt with in a future blog post.</p>
<p>To interpret the usage read the above reduce statement right to left. Thus we start with a default context, and for each key in the sequence of keys, we invoke a lambda (thats like an anonymous function), which calls process key with the context and the key. Note that the first parameter to the lambda is either the initial value (the default context) or the return value of the last process_key (which is also a context) and the key is each key in the keys sequence injected sequentially.</p>
<p>To further make it easy I re-represent the same function below differently which is much more readable and easier to understand. This shows one more strength of python. Because of its focus on readability, it actually can be used to write functional programs are much more readable by a large mass of programmers than most of the functional programming languages themselves (readability being subjectively interpreted by me as what is most natural for english or similar language speaking people).</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> process_keys<span style="color: black;">&#40;</span>keys<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; ctx <span style="color: #66cc66;">=</span> default_context<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> keys :<br />
&nbsp; &nbsp; &nbsp; &nbsp; ctx <span style="color: #66cc66;">=</span> process_key<span style="color: black;">&#40;</span>ctx<span style="color: #66cc66;">,</span>key<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> ctx</div></td></tr></tbody></table></div>
<p><em>Usage</em><br />
As a mechanism to conduct some rudimentary tests on the code written so far, the following code is introduced. Here you can get an overall feel of the program.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">&quot;__main__&quot;</span> :<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">assert</span> process_keys<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'+'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">5</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">assert</span> process_keys<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'!'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'+'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">3</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">assert</span> process_keys<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'@'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">4</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">assert</span> process_keys<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'+'</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'*'</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">25</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">assert</span> process_keys<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'+'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'('</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">3</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'*'</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">5</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">')'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">17</span></div></td></tr></tbody></table></div>
<p><em>Some more slightly advanced Functional Programming</em></p>
<p>Finally to tickle your interest even more, here&#8217;s a slightly more advanced usage of functional programming constructs. Here I shall add all numbers between 1 through 10.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">itertools</span> <span style="color: #ff7700;font-weight:bold;">import</span> chain<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> plus_num_seq<span style="color: black;">&#40;</span>n<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; count <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> count <span style="color: #66cc66;">&lt;=</span> n :<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">yield</span> <span style="color: #483d8b;">'+'</span><span style="color: #66cc66;">,</span> count<br />
&nbsp; &nbsp; &nbsp; &nbsp; count +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span><br />
<br />
keys <span style="color: #66cc66;">=</span> <span style="color: #008000;">list</span><span style="color: black;">&#40;</span>chain.<span style="color: black;">from_iterable</span><span style="color: black;">&#40;</span>plus_num_seq<span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: black;">&#93;</span><br />
<span style="color: #ff7700;font-weight:bold;">assert</span> process_keys<span style="color: black;">&#40;</span>keys<span style="color: black;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">55</span></div></td></tr></tbody></table></div>
<p>The <em>plus_num_seq</em> is a generator. Note the usage of the yield statement. Thus it will continuously generate tuples with the first element of the tuple being the &#8216;+&#8217; character and the second being the number with the number varying from values 1 through n. The <em>chain.from_iterable</em> flattens the generated list (it thus has 20 items for n = 10, each alternate one being the &#8216;+&#8217; character starting with the first items). Since we do not need the very first &#8216;+&#8217; character, I removed it using the [1:] slice operator. </p>
<p>Just like <em>reduce</em> this style of code is quite typical of functional programming. Thats something I shall detail upon much more in future posts. </p>
<p>Hope you enjoyed the post. Keep the feedback coming so I can better structure the subsequent posts based on the feedback. </p>
<p>Note: The full source for the calculator <em>calculator.py</em> can be accessed <a href="http://blog.dhananjaynene.com/wp-content/uploads/2010/02/calculator.py_.txt">here</a>.</p>
<p>Update: I much later also conducted a presentation on the same topic at Pycon India 2010. The slides to the topic can be found at the bottom of <a href="http://in.pycon.org/2010/talks/66-functional-programming-with-python">this page</a> (direct link: <a href="http://in.pycon.org/2010/static/files/talks/66/talk.html">talk.html</a>)</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=39xvqqNOfC4:W9JvDniwzcE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=39xvqqNOfC4:W9JvDniwzcE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=39xvqqNOfC4:W9JvDniwzcE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=39xvqqNOfC4:W9JvDniwzcE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=39xvqqNOfC4:W9JvDniwzcE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=39xvqqNOfC4:W9JvDniwzcE:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/39xvqqNOfC4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/02/functional-programming-with-python-part-1/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/02/functional-programming-with-python-part-1/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=functional-programming-with-python-part-1</feedburner:origLink></item>
		<item>
		<title>Google Buzz Test Drive Report</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/xYHqNPL1m3c/</link>
		<comments>http://blog.dhananjaynene.com/2010/02/google-buzz-test-drive-report/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 00:05:40 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[Internet and Social Media]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[buzz]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[twitter]]></category>

	<!-- AutoMeta Start -->
	<category>buzz</category>
	<category>friendfeed</category>
	<category>inbox</category>
	<category>contacts</category>
	<category>conversation</category>
	<category>graph</category>
	<category>directed</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=964</guid>
		<description><![CDATA[Feature Notes : Note: Google Buzz had not yet been enabled for me through normal GMail Desktop access. These notes are based on my experience with the same by switching my Firefox user agent to iPhone and accessing the iPhone Google Buzz UI. Has a very facebook / friendfeed like interface. Comments : People can [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Feature Notes</strong> :</p>
<p><em>Note: Google Buzz had not yet been enabled for me through normal GMail Desktop access. These notes are based on my experience with the same by switching my Firefox user agent to iPhone and accessing the iPhone Google Buzz UI.</em></p>
<ul>
<li>Has a very facebook / friendfeed like interface.
<ul>
<li><em>Comments</em><strong> :</strong> People can enter comments against a post which appear sequentially below the post.</li>
<li><em>Like</em><strong> :</strong> Has the Like feature also supported by facebook / friendfeed</li>
<li><em>Inline images and videos</em><strong> :</strong> Images and videos appear inline as a part of the stream.</li>
<li><em>No 140 character limitation</em><strong> : </strong> Or at least none that I observed</li>
</ul>
</li>
<li>Each conversation becomes a web page. eg. the <a href="http://www.google.com/buzz/dhananjay.nene/c57YydwHxSX/My-first-test-buzz-post">comment stream</a> against my very first google buzz post.
<ul>
<li>The same conversation is also posted to your inbox. The conversation in the inbox gets dynamically updated as the conversation continues. A conversation that has been read earlier gets marked as unread when more comments are entered against it.</li>
<li>The conversation web page becomes an alternative location for participation. If say the conversation link is forwarded to others, they can immediately comment on (or choose to &#8220;Like&#8221;) the conversation from the web page itself.</li>
</ul>
</li>
<li>Private Channeled Messaging. You can mark posts as private but directed to a group of people. These groups are maintained and managed using <a href="https://www.google.com/contacts">Google Contacts</a>. To the best of my understanding the future conversation is also constrained to the same group. Such messages are obviously not visible publicly. This is an excellent feature for closed group interactions.</li>
<li>Directed messaging is supported using the familiar twitter &#8216;@&#8217; style. However in this case you use &#8216;@&#8217; followed by the entire email address. Any posts made with &#8216;@&#8217; addressing also get delivered to the user&#8217;s inbox.</li>
<li>Geolocation integration is supported. Thus you can view the public posts being made by people nearby you. Since I used firefox, it used firefox for geolocation support. I imagine and presume it would be using alternative superior mechanisms for mobile based conversations.</li>
</ul>
<p><strong>Comparison to Twitter :</strong></p>
<p>One of the reasons I test drove Google Buzz was since I was wondering if it was a better Twitter. In many ways it is. But I don&#8217;t think thats likely to be universally true. There is the 140 character simplicity to twitter which is its identifying feature. In many ways Google Buzz is a Friendfeed clone &#8211; not a twitter clone (with added inbox integration). I always found Friendfeed much superior to twitter for conversations and I suspect those who shared that perception will find Google Buzz far superior to twitter too. However it will run into the same difficulty that Friendfeed did. If the twitter user doesn&#8217;t correlate his twitter account to the friendfeed account, it is very laborious in friendfeed to add a user you follow as an imaginary user in order to have his tweets appear in your friends stream.</p>
<p>I think where Buzz will take on Twitter .. and big time is the really large number of people who sign on to twitter, maybe make a few tweets and then say I don&#8217;t get it and go away. I suspect most of them will &#8220;get it&#8221; on Google Buzz &#8211; especially if they have any Facebook experience (which is a large large set of people). In that sense while Twitter appealed to only a small set of people, Buzz at least has the potential to appeal to the mainstream .. and in that sense go for the jugular &#8211; Facebook&#8217;s that is.</p>
<p><strong>Comparison to Facebook :</strong></p>
<p>Since facebook over a period of time has cloned its update stream to be like that of Friendfeed, it should come as no surprise that the Buzz stream is likely to look and feel quite similar. However two big differences stand out. The first is the way the social graph is managed. The social graph unlike facebook is asymmetric. ie. two persons don&#8217;t have to agree to be friends to follow each other. In case of Buzz, the social graph is managed through google contacts. You can follow people who have public google profiles or follow anyone in your contacts. Thus if a person doesn&#8217;t have a public google profile or his email address is not known to you, you may not be able to follow him/her. You don&#8217;t need the other person&#8217;s permission to follow. (At least thats the impression I formed, though I could stand corrected). The other big difference is the email integration. The entire stream and conversations are integrated into the gmail account. For most knowledge workers, I think these differences are likely to make for a more positive experience. In that sense &#8211; buzz is extremely well suited to be the Facebook of knowledge workers. Whether it can compete with the trivial, frivolous, chatty social networking capabilities of Twitter or Facebook is something I couldn&#8217;t form a clear opinion on.</p>
<p><strong>On carving a new market :</strong></p>
<p>Based on my earlier statements, it should be obvious that I believe buzz will carve new markets which did not use Facebook / Twitter / Friendfeed earlier. These markets are :</p>
<ul>
<li>People who tried twitter but didn&#8217;t get it</li>
<li>People who primarily use email for communications instead of facebook / twitter (for both Personal and Business Networking)</li>
<li>People who would like to use Facebook / Twitter like capabilities from a knowledge working / business perspective.</li>
<li>People who are just too nervous to use anything new on the net may still find the email integration a continuum of their email exchange rather than a &#8216;new web site&#8217;.</li>
</ul>
<p><strong>On Privacy :</strong></p>
<p>I think Buzz definitely ranks superior on privacy, given its capability to conduct private directed closed group conversations. As an example, I can imagine many google apps installations which could use buzz for intra company conversations even as they clearly restrict even the public streams not to be visible outside the domain. While I haven&#8217;t seen any comment from Google on whether buzz would be available for google apps, I imagine its only a matter of time since it is so particularly well suited for that environment.</p>
<p><strong>On google wave :</strong></p>
<p>Google wave in many ways was a damp squib. It imposed a new usability paradigm even as some of the capabilities such as near real time updates were clearly superb. Google buzz reverses the wave approach by offering a different conversation model which dovetails not only into similar usability expectations as defined by the competition but goes one step beyond by integrating into the killer web application &#8211; web mail. I wouldn&#8217;t be surprised if it came to light later that Google buzz is a google wave backend with a completely new usability experience.</p>
<p><strong>A note on integration :</strong></p>
<p>While its only a statement of intent at this stage, google has setup a site for the <a href="http://code.google.com/apis/buzz/">Google Buzz API</a>. However the promise is awesome in terms of multi standard support for variety of standards and protocols support including RSS, Atom, PubSubHubbub, Social Graph API, OAuth, WebFinger and Salmon. It does seem that google will want to support a variety of other alternative and mashup use cases around Google Buzz which might allow for more interesting uses to emerge (as it happened for Facebook and Twitter). Clearly a space to watch with some interest in months to come.</p>
<p><strong>In summary :</strong></p>
<p>Google buzz makes the strongest case for appealing to the power email users and those particularly focused on privacy (eg. knowledge working for businesses). Its strong differentiator is its mail integration. It does offer adequate features to compete with Facebook / Twitter for their existing markets as well. And joins the party with a large number of people &#8211; who already have a google account.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=xYHqNPL1m3c:dw4Kl6WoPxw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=xYHqNPL1m3c:dw4Kl6WoPxw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=xYHqNPL1m3c:dw4Kl6WoPxw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=xYHqNPL1m3c:dw4Kl6WoPxw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=xYHqNPL1m3c:dw4Kl6WoPxw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=xYHqNPL1m3c:dw4Kl6WoPxw:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/xYHqNPL1m3c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/02/google-buzz-test-drive-report/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/02/google-buzz-test-drive-report/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=google-buzz-test-drive-report</feedburner:origLink></item>
		<item>
		<title>Software development is about the middle and not just the end</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/1HYRVQXsCMw/</link>
		<comments>http://blog.dhananjaynene.com/2010/01/software-development-is-about-the-middle-and-not-just-the-end/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 13:45:07 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[management]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[sports]]></category>

	<!-- AutoMeta Start -->
	<category />
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=950</guid>
		<description><![CDATA[Software development often gets similar treatment as other disciplines when it comes to matters of management. Often at a cost. And the cost comes from the fact that, the learnings and best practices gleaned from a number of disciplines are hard to apply in the field of software development, without understanding and dealing with some [...]]]></description>
			<content:encoded><![CDATA[<p>Software development often gets similar treatment as other disciplines when it comes to matters of management. Often at a cost. And the cost comes from the fact that, the learnings and best practices gleaned from a number of disciplines are hard to apply in the field of software development, without understanding and dealing with some of the essential differences. And those differences and their implications are what this post explores.</p>
<p>There was an interesting post recently <a href="http://conal.net/blog/posts/why-program-with-continuous-time/">Why program with continuous time?</a>.</p>
<blockquote><p>Today I read a confusion that I’ve heard many times before about continuous time, which I’d like to bring up, in part because I love continuous time, and in part because there’s a much broader underlying principle of software design.</p>
<blockquote><p>I don’t see why the lack of continuous streams leaves a “gap”. In the end all streams are discrete</p></blockquote>
<p>“In the end”, yes. Just as in the end, numbers are displayed as ascii numerals. However, programming is more about the middle than the end, i.e., more about composition than about output. &#8230; Similarly, continuity in space and in time is better for composition/modularity, leaving discreteness to the output step.</p></blockquote>
<p>The post above is completely unrelated to management. Its talking about a programming style called Functional Reactive Programming. But an idea it eloquently brings out is  <em>programming is more about the middle than the end, i.e., more about composition than about output</em>. And thats a thought that I would like to expand upon.</p>
<p>While arguably in all disciplines the middle is also important, I would emphasise that it is particularly more so in software development. And that stems from a number of uncertainties that abound in software. The requirements are often not available in adequate detail, and to the extent available, are not stable. Moreover solutions to these problems are not all thought through upfront. Not because people don&#8217;t do their homework &#8211; its simply because it is actually extremely difficult to visualise all the moving parts, and then anticipate and resolve all the challenges. In fact many of the challenges don&#8217;t show up until you start programming. Thus programming often is an exercise in identifying surprises, resolving them, working out algorithms, discovering flaws with them, fixing these flaws only to find more surprises. Rinse and repeat. Basically its a significant exercise in uncertainty management. In such a situation, estimation results in underestimates since these are based on visible not actual challenges and surprises. The solution that does get applied with some success is to use historic estimation errors to compensate current estimates. (Note that thats not always obvious since the estimate could have the compensation already built in).</p>
<p>To add to the problem there is usually no Bridge 2.0, Lathe 2.0 or a Marketing Campaign 2.0 (and to the extent there might be some, these are far less dependent upon the quality of the work that went into the 1.0). Some programmers are continuously focused on 1.0, while many are thinking about the 10.0 even as they work on the 1.0.  Optimising for 1.0 alone may not be the right way to approach an initiative. In the good old design methodology one attempted to anticipate and build for a lot of future changes. This requires a lot of extra complexity and development in terms of layering, parameterisation, open extensibility etc. In conventional agile methodologies the focus is much more on the 1.0, but there is a deliberate and definite cost introduced in terms of creation of a large number of automated test cases. These automated test cases is the assurance premium to be paid, in order to provide the comfort to undertake the necessary refactoring challenges when moving from 1.0 to 2.0. Thus whichever way one looks at it, the 1.0 is always suboptimised to allow for a more optimal 2.0, 3.0 etc. (note: I am referring to 1.0 figuratively as the current initiative and higher version numbers to future initiatives building on the current one). But selection of the necessary suboptimisations, with a view to optimise the overall sequence, requires a substantial understanding of the software development processes, the code, the tools etc.</p>
<p>Finally programming has a far far higher human element involved than other disciplines. After all there&#8217;s hardly any raw material dependency and the tooling is often a desktop, the cloud and set of open source libraries. Thus it is subject to the vagaries and frailties of human behaviour. Coordination, Communication, Productivity, are all held hostage by this fickle human element. While programming is not unique in this respect, achieving high team productivity is as much a function of morale, motivation, and communication as perhaps any other discipline. Thus progress is often non linearly proportional to such soft factors.</p>
<p>I believe there&#8217;s some benefit in evaluating software development management styles with how sports teams are managed. In sports, team performances are rarely consistent. Moreover even though team playing skills are critical, raw talent is also very important. But the analogy is most appropriate when one evaluates the game. The game is often a series of surprises reacted to by immediate on the fly action. Thats where adaptability and ability to counter attack surprises, can be effectively brought to bear. And in sports as in software development, player morale and motivation needs to be enhanced even as the player arrogance or dysfunctional behaviours are contained.</p>
<p>Since different sports are structured differently let me clarify the roles here. In some cases the manager and coach are different. In others they are vested in the same person. In my mind the manager&#8217;s role is resource management, broader strategy planning, impediment removal and stakeholder communication. The role of the coach is to enhance team skills, ensure fitness and training, and in case of many sports actively guide the team in refining the on field strategy when the game is in progress. Now lets consider the players. In most cases the players are living the game. They are in the middle. A substantial portion of their interesting professional time is spent in the middle. And when they are doing that, they are continuously dealing with a set of constant surprises, even as they broadly attempt to achieve the deliverables required for the end. A slight difference between sports and software development is that in case of sports the time is fixed and the score is variable. In case of software development at least in the non agile world, the score (feature set) is fixed and the time therefore becomes the variable. But the interesting takeaway from this analogy is that once the game starts, the ends become the background and the game dominates. The players and the developers are all living in the middle.</p>
<p>Why is this particularly relevant ? It is so because it helps us understand the implication of management styles in software development teams performance. If one wants to optimise &#8211; one needs to very well understand the middle and not just the ends. And (to come to the point) thats where I have a big issue with software developers, who end up imagining that as they rise up in the hierarchy, they somehow can stop worrying about coding and quality assurance, and instead start focusing only on managing people and deadlines. Thats a mistake. Since the game is played in the middle, you need to be able to help your team play the game. And you need to do it as a coach or a captain.  For that, so long as you want to manage an ongoing game, you need to keep on playing and keep on being either sufficiently conversant about whats happening in the middle or be the captain and play the game with the team. Thinking that somehow you&#8217;ve grown in stature enough to not worry about the tactics, and focus on things increasingly strategic might actually make you unhelpful. The game requires skill and continuous adaptation &#8211; and you will need to be able to play, until you one day decide, you are no longer interested in managing the game but only the periods between.</p>
<p>The non playing managers who attempt to manage the game on the other hand display some interesting smells. They stop understanding the sport. They start believing that since they had played some particular sport many years ago, its easy for them to now manage any other sport. They are unable to appreciate the actual game play that happens. So when required to score a particular number of goals in 90 minutes (say in soccer), they start pushing in more team members (alas, this is a luxury not available to sports teams). Now on field coordination starts getting more difficult. The newer members being relatively junior are the ones who start getting intercepted more often (thus the team keeps on losing the ball more frequently).  If the team luck is all run out, the same managers also attempt to run the tactics and gameplay selection. This is based on some fairly old set of experiences. The spectators (customers) start seeing far more confusion on the field. And the objectives change from playing the game well to just scoring the required number of goals. And in the end the spectators may get to see the number of goals promised, but only through a confused dissatisfying game, and that too sometimes only after many bouts of extra time. And soon enough once the non playing managers realise they are unable to effectively control the game play, they try to manage other variables. But really whats starting to happen is that they are hurting the gameplay, and sometimes instead of managing the game, they start managing the spectators with the game on autoplay. Suboptimisation maximised. Alas, sometimes the spectators also get used to this and start forgetting what a good game used to be like.</p>
<p>To summarise, ends are good to have, ends are important, ends provide the background urgency. But software development is not so much about managing the end goals as much as managing the middle. If you want to build good software and help your team build good software, make sure you continue to focus on how software is built not just the quantitative targets. Make sure you live and enjoy the middle. More often than not, the ends you achieve eventually could be amongst the best possible ends that were practical &#8211; but more importantly the customers will also go home satisfied. So long as you keep your eye on the ball and don&#8217;t lose sight of the middle. And if you want to view it a bit philosophically, in the end we are all dead. Only the middle matters.</p>
<p><em>Authors Note : This post has been substantially revised from its earlier version from a syntax, grammar and punctuation perspective. And the philosophical note (the last line) was added later.</em></p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1HYRVQXsCMw:-8WklZHzwK4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1HYRVQXsCMw:-8WklZHzwK4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=1HYRVQXsCMw:-8WklZHzwK4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1HYRVQXsCMw:-8WklZHzwK4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=1HYRVQXsCMw:-8WklZHzwK4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=1HYRVQXsCMw:-8WklZHzwK4:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/1HYRVQXsCMw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/01/software-development-is-about-the-middle-and-not-just-the-end/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/01/software-development-is-about-the-middle-and-not-just-the-end/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=software-development-is-about-the-middle-and-not-just-the-end</feedburner:origLink></item>
		<item>
		<title>Concise python code</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/zY21wajviN4/</link>
		<comments>http://blog.dhananjaynene.com/2010/01/concise-python-code/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 20:19:59 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[functional programming]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

	<!-- AutoMeta Start -->
	<category>clojure</category>
	<category>clojure</category>
	<category>employee</category>
	<category>ndepartment</category>
	<category>ndepartment</category>
	<category>department</category>
	<category>department</category>
	<category>groupby</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=937</guid>
		<description><![CDATA[I love python for a number of reasons. Brevity is one of them. Readability is another. However writing readable concise code can take some time to getting used to. This post discusses some code snippets especially in the context of some of the comparisons done between python and clojure &#8211; another language which excels at [...]]]></description>
			<content:encoded><![CDATA[<p>I love python for a number of reasons. Brevity is one of them. Readability is another. However writing readable concise code can take some time to getting used to. This post discusses some code snippets especially in the context of some of the comparisons done between python and clojure &#8211; another language which excels at brevity and shares yet another feature with python, ie. people either love or hate its syntax, they are rarely indifferent to it.</p>
<p>Please note : The intent of this post is not to compare LOC of python with other languages. It is meant to demonstrate python code implementation which helps describe the capabilities of python in terms of writing clean, concise, readable code. This post continuously refers to other posts and may require you to read the referred posts in conjunction with this post to get maximum value.</p>
<p><strong>Code and ceremony</strong></p>
<p>The post <a href="http://www.bestinclass.dk/index.php/2009/09/java-vs-clojure-lets-talk-ceremony/">Java vs Clojure – Lets talk ceremony!</a> describes a simple problem which requires 28 LOC in Java and 1 or 9 in clojure. It is a simple logic which creates a list, populates it with four values (two of them identical) and creates a list with unique items. There are two alternative clojure implementations, one in 1 line of code and another in 9 &#8211; the former using a built in construct in the language which especially helps to write a more concise logic, and the latter by writing code similar to the Java code. Without any further ado, here are the two alternative python implementations</p>
<p>a. By using built in capabilities &#8211; In this case we use the set collection</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;foo&quot;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">&quot;bar&quot;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">&quot;baz&quot;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">&quot;foo&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>b. Now here&#8217;s where we will not use a built in operator which automatically chooses the unique elements but again write code similar to the java code. This code is as follows :</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">reduce</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x<span style="color: #66cc66;">,</span>y: &nbsp;x + <span style="color: black;">&#91;</span>y<span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">if</span> y <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> x <span style="color: #ff7700;font-weight:bold;">else</span> x <span style="color: #66cc66;">,</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;foo&quot;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">&quot;bar&quot;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">&quot;baz&quot;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">&quot;foo&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>There &#8211; both of them are exactly one line long.</p>
<p><strong>Project Euler solutions</strong><br />
The post <a href="http://www.bestinclass.dk/index.php/2009/10/python-vs-clojure-evolving/">Python vs Clojure – Evolving</a> refers to many sample python implementations solving some of the problems documented on <a href="http://projecteuler.net">project euler</a> site. We shall revisit these python implementations here.</p>
<p>a. <em>Find all numbers dividable by 3 or 5 in 0 < x < 1000</em>:<br />
In this case the clojure code is 4 lines long where as the python implementation is 3 lines long</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>i <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">1000</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> i%<span style="color: #ff4500;">3</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">or</span> i%<span style="color: #ff4500;">5</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Again the implementation is exactly 1 line long &#8211; no lambdas, no filters etc.</p>
<p>b. <em>Get the sum of all even Fibonaccis below 4 mill.</em></p>
<p>The suggested python implementation is about 17 lines long. The implementation below 7.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">itertools</span> <span style="color: #ff7700;font-weight:bold;">import</span> takewhile<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> fib<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; x<span style="color: #66cc66;">,</span>y <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">1</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; x<span style="color: #66cc66;">,</span>y <span style="color: #66cc66;">=</span> y<span style="color: #66cc66;">,</span>x+y<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">yield</span> x<br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>i <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> takewhile<span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x : x <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">4000000</span><span style="color: #66cc66;">,</span>fib<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> i%<span style="color: #ff4500;">2</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>c. <em>Finding Palindromes</em><br />
The suggested python solution uses about 23 lines of code, to 6 in clojure and takes <strong>15</strong> seconds almost <strong>300%</strong> slower than the clojure code (emphasis from the post referred to).</p>
<p>Here&#8217;s another alternative implementation.</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">max</span><span style="color: black;">&#40;</span>x * y <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">1000</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> y <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span><span style="color: #66cc66;">,</span><span style="color: #ff4500;">1000</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>x*y<span style="color: black;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>x*y<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>::-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Again if you notice &#8211; exactly one line of code. And incidentally on my notebook it clocks in about <strong>0.85</strong> seconds which makes the clojure implementation about <strong>470%</strong> slower than the python implementation. (emphasis mine)</p>
<p><strong>Top Rank Per Group</strong></p>
<p>In yet another post <a href="http://www.bestinclass.dk/index.php/2009/10/python-vs-clojure-reloaded/">Python vs Clojure – Reloaded</a>, the author discusses the <a href="http://rosettacode.org/wiki/Top_Rank_Per_Group">Rosetta Top Rank Per Group</a> implementation of python. Unsurprisingly the python implementation uses 11 lines of code (not including the initialisation) compared to clojure&#8217;s 6. </p>
<p>One of the commenters suggests an <a href="http://gist.github.com/214369">eminently readable and simple python solution</a> in about 6 lines of code. The code snippet is as follows</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">itertools</span> <span style="color: #ff7700;font-weight:bold;">import</span> groupby<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">operator</span> <span style="color: #ff7700;font-weight:bold;">import</span> itemgetter<br />
<br />
data <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;Tyler Bennett&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">id</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;E10297&quot;</span><span style="color: #66cc66;">,</span> salary<span style="color: #66cc66;">=</span><span style="color: #ff4500;">32000</span><span style="color: #66cc66;">,</span> department<span style="color: #66cc66;">=</span><span style="color: #483d8b;">&quot;D101&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> ...<span style="color: black;">&#93;</span><br />
<br />
department <span style="color: #66cc66;">=</span> itemgetter<span style="color: black;">&#40;</span><span style="color: #483d8b;">'department'</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> dep<span style="color: #66cc66;">,</span> persons <span style="color: #ff7700;font-weight:bold;">in</span> groupby<span style="color: black;">&#40;</span><span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>data<span style="color: #66cc66;">,</span> key<span style="color: #66cc66;">=</span>department<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> department<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Department&quot;</span><span style="color: #66cc66;">,</span> dep<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot; Employee Name &nbsp; Employee ID &nbsp; &nbsp; Salary &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Department&quot;</span> &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> person <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>persons<span style="color: #66cc66;">,</span> key<span style="color: #66cc66;">=</span>itemgetter<span style="color: black;">&#40;</span><span style="color: #483d8b;">'salary'</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;%(name)-15s %(id)-15s %(salary)-15s %(department)-15s&quot;</span></div></td></tr></tbody></table></div>
<p>An alternative far less readable solutions which shaves off one more line but certainly not preferred to the solution above (am just listing it since it shaves off the step of having to create an intermediate data structure) is</p>
<div class="codecolorer-container python dawn" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">operator</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">itertools</span> <span style="color: #ff7700;font-weight:bold;">import</span> groupby<br />
&nbsp; &nbsp;<br />
data <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Employee Name'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Employee ID'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Salary'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Department'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span>....<span style="color: black;">&#93;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">reduce</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x<span style="color: #66cc66;">,</span>y : x + y<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>Department %s<span style="color: #000099; font-weight: bold;">\n</span> &nbsp;Employee Name &nbsp; Employee ID &nbsp; &nbsp; Salary &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Department &nbsp;'</span> % dept + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">reduce</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x<span style="color: #66cc66;">,</span>y : x + <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span> &nbsp;&quot;</span> + <span style="color: #483d8b;">&quot;%-15s &quot;</span> * <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> % y<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>recs<span style="color: #66cc66;">,</span> key<span style="color: #66cc66;">=</span><span style="color: #ff7700;font-weight:bold;">lambda</span> rec: -rec<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:<span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">for</span> dept<span style="color: #66cc66;">,</span> recs <span style="color: #ff7700;font-weight:bold;">in</span> groupby<span style="color: black;">&#40;</span><span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span>key<span style="color: #66cc66;">=</span><span style="color: #dc143c;">operator</span>.<span style="color: black;">itemgetter</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">lambda</span> x : x<span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Some might wonder whether I am joining multiple lines of code into one just to reduce the line count. The code is consistent with the idiomatic usage of python and also with the way python list comprehensions are documented in the formal python proposal for list comprehensions <a href="http://www.python.org/dev/peps/pep-0202/">PEP 202 : List Comprehensions</a>. Besides python is a whitespace sensitive language and the compiler disallows multiple lines of code in one line without using the &#8216;;&#8217; separator which I have most definitely not used in the suggested solutions.</p>
<p>PS: There&#8217;s of course an interesting image at the end of the post <a href="http://www.bestinclass.dk/index.php/2009/10/python-vs-clojure-reloaded/">Python vs Clojure – Reloaded</a> indicating the perception of how clojure code speaks for itself <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . The reason I mention it is that I believe if one is expressing a strong opinion as the one reflected by the picture, one better be far more careful and thorough with verifying the <del datetime="2010-01-05T20:44:10+00:00">veracity of the assertions</del> <ins datetime="2010-01-05T20:44:10+00:00">appropriateness of the samples compared to</ins>. Let me clearly state that I do not know that the clojure loc compared to is an appropriate target so do not infer this post to be a Python vs Clojure LOC as much as a post which emphasises that Python is a good vehicle to write concise readable code. FWIW I am learning clojure and look forward to building more competence with it.</p>
<p><ins datetime="2010-01-05T20:23:24+00:00">Update:</ins> There is another nice post by Stephan Schmidt &#8211; <a href="http://codemonkeyism.com/scala-vs-clojure-flawed-loc-comparison/">Anatomy of a Flawed Clojure vs. Scala LOC Comparison</a> which does reflect an opinion in the context of Scala and a post authored on the same blog as the ones I refer to above.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=zY21wajviN4:JE76a6hz53Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=zY21wajviN4:JE76a6hz53Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=zY21wajviN4:JE76a6hz53Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=zY21wajviN4:JE76a6hz53Y:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=zY21wajviN4:JE76a6hz53Y:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=zY21wajviN4:JE76a6hz53Y:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/zY21wajviN4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2010/01/concise-python-code/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2010/01/concise-python-code/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=concise-python-code</feedburner:origLink></item>
		<item>
		<title>Post conference recap : The 4th Indicthreads.com conference on Java Technology</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/G5GjsTf7uq8/</link>
		<comments>http://blog.dhananjaynene.com/2009/12/post-conference-recap-the-4th-indicthreads.com-conference-on-java-technology/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 14:31:12 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[indicthreads]]></category>

	<!-- AutoMeta Start -->
	<category />
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=928</guid>
		<description><![CDATA[The annual indicthreads.com java technology conference is Pune&#8217;s best and possibly one of India&#8217;s finest conferences on matters related to Java technologies. I looked forward to attending the same and was not disappointed a bit. The last one was held about 3 days ago on Dec 11th and 12th, and this post reviews my experiences [...]]]></description>
			<content:encoded><![CDATA[<p>The annual <a href="http://indicthreads.com">indicthreads.com</a> java technology conference is Pune&#8217;s best and possibly one of India&#8217;s finest conferences on matters related to Java technologies. I looked forward to attending the same and was not disappointed a bit. The last one was held about 3 days ago on Dec 11th and 12th, and this post reviews my experiences at the same.</p>
<p>As with any other conference usually something or the other isn&#8217;t quite working well in the morning, so I soon discovered we had a difficulty with the wireless network being swamped by the usage. There were some important downloads that needed to be completed, so my early morning was spent attempting to get these done .. which meant I missed most of <em>Harshad Oak</em>&#8216;s opening session on <em>Java Today</em>. </p>
<p>The next one i attended was <em>Groovy &#038; Grails as a modern scripting language for Web applications</em> by <em>Rohit Nayak</em>. However I soon discovered that it (at least initially) seemed to be a small demo on how to build applications using grails. Since that was something I was familiar with, I moved to the alternative track in progress.</p>
<p>The one I switched to even as it was in progress was <em>Java EE 6: Paving the path for the future</em> by <em><a href="http://java.sun.com/developer/Meet-Eng/gupta/">Arun Gupta</a></em>. Arun had come down from Santa Clara to talk about the new Java EE6 spec and its implementation by Glassfish. Arun talked about a number of additional or changed features in Java EE6 in sufficient detail for anyone who got excited by them to go explore these in further detail. These included web fragments, web profile, EJB 3.1 lite, increased usage of annotations leading to web.xml now being optional, and a number of points on specific JSRs now a part of Java EE6. Some of the things that excited me more about Glassfish were, (a) OSGi modularisation and programmatic control of specific containers (eg Servlet, JRuby/Rails etc.), embeddability, lightweight monitoring. However the one that excited me the most was the support for hot deployment of web apps for development mode by allowing the IDEs to automatically notify the running web app which in turn automatically reloaded the modified classes (even as the sessions continued to be valid). The web app restart cycle in addition to the compile cycle was alway one of my biggest gripes with Java (second only to its verbosity) and that seemed to be going away. </p>
<p>I subsequently attended <em>Getting started with Scala</em> by <em>Mushtaq Ahmed</em> from Thoughtworks. Mushtaq is a business analyst and not a professional programmer, but has been keenly following the developments in Scala for a couple of years (and as I later learnt a bit with Clojure as well). Unlike a typical language capability survey, he talked only about using the language for specific use cases, a decision which I thought made the presentation extremely useful and interesting. The topics he picked up were (a) Functional Programming, (b) DSL building and (c) OOP only if time permitted. He started with an example of programming/modeling the Mars Rover movements and using functions and higher order functions to do the same. Looking back I think he spent lesser time on transitioning from the requirements into the code constructs and in terms of what he was specifically setting out to do in terms of higher order functions. However the demonstrated code was nevertheless interesting and showed some of the power of Scala when used to write primarily function oriented code. The next example he picked up was a Parking Lot attendant problem where he started with a Java code which was a typical implementation of the strategy pattern. He later took it through 7-8 alternative increasingly functional implementations using Scala. This one was much easier to understand and yet again demonstrated the power of Scala quite well in terms of functional programming. Onto DSLs, Mushtaq wrote a simple implementation of a &#8220;mywhile&#8221; which was a classical &#8220;while&#8221; loop as an example of using Scala for writing internal DSLs. Finally he demonstrated the awesome power of using the built in support for parser combinators for writing an external DSL, and also showed how a particular google code of summer problem could be solved using Scala (again for writing an external DSL). A very useful and thoroughly enjoyable talk.</p>
<p>The brave speaker for the post lunch session was Rajeev Palanki who dealt both with overall IBM directions on Java and a little about <a href="https://www.ibm.com/developerworks/mydeveloperworks">MyDeveloperworks</a> site. In his opinion he thought Java was now (post JDK 1.4) on the plateau of productivity after all the early hype and IBM now focused on Scaling up, Scaling down (making it easier to use at the lower end), Open Innovation (allow for more community driven innovation) and Real Time Java. He emphasised IBMs support to make Java more predictable for real time apps and  stated that Java was now usable for Mission Critical applications referring to the fact that Java was now used in a USS Destroyer. He referred to IBMs focus on investing in Java Tooling that worked across different JRE implementations. Tools such as <a href="http://www.ibm.com/developerworks/java/jdk/tools/gcmv/">GCMV</a>, <a href="http://www.ibm.com/developerworks/java/jdk/tools/memoryanalyzer/">MAT</a>, and <a href="http://www.ibm.com/developerworks/java/jdk/tools/diagnosticscollector/">Java Diagnostic Collector</a>. Finally he talked about the IBM MyDeveloperWorks site at one stage referring to it as the Facebook for Geeks.</p>
<p>The next session was <em>Overview of Scala Based Lift Web Framework</em> by <em>Vikas Hazarati</em>, Director, Technology at Xebia. Another thoroughly enjoyable session. Vikas dealt with a lot of aspects related to the Lift web framework including various aspects related to the mapper, the snippets, usage of actors for comet support etc. I was especially intrigued by Snippets which act as a bridge between the UI and the business logic have a separate abstraction for themselves in the framework and how the construct and functionality in that layer is treated so differently from other frameworks.</p>
<p>I subsequently attended <em>Concurrency: Best Practices</em> by Pramod Nagaraja who works on the IBM JRE and owns the java.nio packages (I think I heard him say owns). He talked about various aspects and best practices related to concurrency and one of the better aspects of the talk was how seemingly safe code can also end up being unsafe. However he finished his session well in time for me to quickly run over and attend the latter half of the next presentation.</p>
<p>Arun Gupta conducted the session <em>Dynamic Languages &#038; Web Frameworks in GlassFish</em> which referred to the support for various non java environments in Glassfish including those for Grails/Groovy, Rails/JRuby, Django/Python et. al. The impression I got was Glassfish is being extremely serious about support for the non java applications as well and is dedicating substantial efforts to make Glassfish the preferred platform for such applications as well. Arun&#8217;s blog <a href="http://blogs.sun.com/arungupta/">Miles to go &#8230;</a> is most informative for a variety of topics related to Glassfish for both Java and non Java related aspects.</p>
<p>The last talk I attended during the day was <em>Experiences of Fully Distributed Scrum between San Francisco and Gurgaon</em> by <em>Narinder Kumar</em>, again from Xebia. Since a few in the audience were still not aware of agile methodologies (Gasp!), Narinder gave a high level overview of the same before proceeding down the specific set of challenges his team had faced in implementing scrum in a scenario where one team was based in Gurgaon, India and another in San Fransciso, US. To be explicit, he wasn&#8217;t describing the typical scrum of scrum approaches but was instead describing a mechanism wherein the entire set of distributed teams would be treated as a single team with a single backlog and common ownership. This required some adjustments such as a meeting where only one person from one of the locations and all from another would take part in a scrum meeting in situations where there were no overlapping working hours. There were a few other such adjustments to the process also described. The presentation ended with some strong metrics which represented how productivity was maintained even as the activities moved from a single location to a distributed model. Both during the presentation and subsequently Narinder described some impressive associations with senior Scrum visionaries and also some serious interest in their modified approach from some important companies. However one limitation I could think of the model was, that it was probably better geared to work where you had developers only in one of the two locations (offshoring). I perceived the model as a little difficult to work if developers were located across all locations (though that could end up being just my view).</p>
<p>The second day started with a Panel Discussion on the topic <em>Turning the Corner</em> between Arun Gupta, Rohit Nayak, Dhananjay Nene (thats yours truly) and moderated by Harshad Oak. It was essentially a discussion about how we saw some of the java and even many non java related technologies evolving over the next few years. I think suffice to say one of the strong agreements clearly was the arrival of Java the polyglot platform as compared to Java the language. </p>
<p>The next session was <em>Developing, deploying and monitoring Java applications using Google App Engine</em> by Narinder Kumar. A very useful session describing the characteristics, opportunities and challenges with using Google App Engine as the deployment platform for Java based applications. One of the take away from the sessions was that subject to specific constraints, it was possible to use GAE as the deployment platform without creating substantial lockins since many of the Java APIs were supported by GAE. However there are a few gotchas along the way in terms of specific constraints eg. using Joins etc. </p>
<p>I must confess at having been a little disappointed with <em>Automating the JEE deployment process</em> by Vikas Hazrati. He went to great depths in terms of what all considerations a typical J2EE deployment monitoring tool should take care of, and clearly demonstrated having spent a lot of time in thinking through many of the issues. However the complexities he started addressing started to get into realms which only a professional J2EE deployment tool writer would get into. That made the talk a little less interesting for me. Besides there was another interesting talk going on simultaneously which I was keen on attending as well.</p>
<p>The other talk I switched to half way was <em>Create Appealing Cross-device Applications for Mobile Devices with Java ME and LWUIT</em> by Biswajit Sarkar (who&#8217;s also written a book on the same topic). While keeping things simple, Biswajit explained the capabilities of Java ME. He also described LWUIT which allowed creation of largely similar UI across different mobile platforms. He explained that while the default Java ME used native rendering leading to differing look and feel across mobile handsets just like Java AWT, using LWUIT allowed for a Java Swing like approach where the rendering was performed by the LWUIT library (did he say around 300kb??)  thus allowing for a more uniform look and feel. He also showed sample programs and how they worked using LWUIT. </p>
<p>Allahbaksh Asadullah then conducted the session on <em>Implementing Search Functionality With Lucene &#038; Solr</em>, where he talked about the characteristics and usage of Lucene and Solr. It was very explicitly addressed at the very beginners to the topic (an audience I could readily identify myself with) and walked us through the various characteristics of search, the different abstractions, how these abstractions are modeled through the API and how some of these could be overridden to implement custom logic. </p>
<p><em>How Android is different from other systems – An exploration of the design decisions in Android </em> by Navin Kabra was a session I skipped. However I had attended a similar session by him earlier so hopefully I did not miss much.</p>
<p>However Navin did contribute occasionally into the next session <em>Java For Mobile Devices – Building a client application for the Android platform</em> by Rohit Nayak. Rohit demonstrated an application he is working on along with a lot of the code that forms the application using Eclipse and the Android plugin. A useful insight into how an Android application is constructed.</p>
<p>As the event drew to a close, the prizes were announced including those for the <a href="http://j09.indicthreads.com/indicthreads-go-green/">Indicthreads Go Green</a> initiative. A thoroughly enjoyable event, leaving me even more convinced to make sure to attend the next years session making it a third in a row.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=G5GjsTf7uq8:eqsb9s8aUa8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=G5GjsTf7uq8:eqsb9s8aUa8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=G5GjsTf7uq8:eqsb9s8aUa8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=G5GjsTf7uq8:eqsb9s8aUa8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=G5GjsTf7uq8:eqsb9s8aUa8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=G5GjsTf7uq8:eqsb9s8aUa8:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/G5GjsTf7uq8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/12/post-conference-recap-the-4th-indicthreads.com-conference-on-java-technology/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/12/post-conference-recap-the-4th-indicthreads.com-conference-on-java-technology/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=post-conference-recap-the-4th-indicthreads.com-conference-on-java-technology</feedburner:origLink></item>
		<item>
		<title>Rinse and Repeat with TDD</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/3UTOFhCPs9s/</link>
		<comments>http://blog.dhananjaynene.com/2009/11/rinse-and-repeat-with-tdd/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 15:01:49 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[tdd]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=921</guid>
		<description><![CDATA[I must confess having had a awed love relationship with TDD (Test Driven Development). This is the style where you first write the test cases and then write the code to make them pass. I&#8217;ve always felt awed by it. I have always firmly believed that it is the right way to offer sustainable quality. [...]]]></description>
			<content:encoded><![CDATA[<p>I must confess having had a awed love relationship with TDD (<a href="http://en.wikipedia.org/wiki/Test-driven_development">Test Driven Development</a>). This is the style where you first write the test cases and then write the code to make them pass. I&#8217;ve always felt awed by it. I have always firmly believed that it is the right way to offer sustainable quality. As someone who hasn&#8217;t been particularly awed by separate QA teams, I have always imagined TDD to be the silver bullet to offer controlled, sustained, high quality. Well, the silver bullet is a bit of an exaggeration, but sounded nice while I was on a roll <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . A number of times I wrote automated test cases post facto. But when the rubber met the road &#8211; I didn&#8217;t ever implement TDD. </p>
<p>Its probably a function of style. I like to write a piece of code and then keep on testing it against different scenarios and often keep on remoulding it substantially. My focus is at this stage on the code structure &#8211; the design aspects. Trying to do it with TDD always created a mess. The amount of intense refactoring I do always meant I soon got tired of also simultaneously refactoring the test cases and gave up on them soon. </p>
<p>Anyways, I finally think I found a formula that works &#8211; at least for me. I do not write production code in the first pass. I just write prototype code. I keep on playing with it, shaping it, challenging it, cajoling it, recasting it. Until I&#8217;m satisfied with the overall structure and internal design. Now when thats done, I rewrite it. Completely. Umm, I copy/paste maybe 40-50% of the code. But this time I write it on a completely new fresh set of files. And I write the test cases before I write the code. I find I can now really write tons of test cases and code quite rapidly. And with the tremendous satisfaction that at the end of the day, I now have the control harness to be able to keep on adding new features without having to continuously worry if I broke something else. With substantially detailed test cases, now I can actually feel quite confident that if I did break something &#8211; I&#8217;ll get to know it. Not next month, not next week, not even tomorrow &#8211; in the next few minutes.</p>
<p>So this approach seems to be working for me &#8211; the initial efforts have delivered great results and I&#8217;m quite satisfied. Now just wondering what to call it &#8211; for lack of a better term I shall term it &#8220;Rinse and Repeat with TDD&#8221;.</p>
<p>So if TDD works for you &#8211; great. You have one of the most important coding disciplines nailed down. But if you&#8217;re wanting to try to do TDD but haven&#8217;t been able to successfully implement it &#8211; you may just want to check out the Rinse and Repeat with TDD style. Who knows, you might find it useful too.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=3UTOFhCPs9s:YTbGwYkJ3RQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=3UTOFhCPs9s:YTbGwYkJ3RQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=3UTOFhCPs9s:YTbGwYkJ3RQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=3UTOFhCPs9s:YTbGwYkJ3RQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=3UTOFhCPs9s:YTbGwYkJ3RQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=3UTOFhCPs9s:YTbGwYkJ3RQ:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/3UTOFhCPs9s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/11/rinse-and-repeat-with-tdd/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/11/rinse-and-repeat-with-tdd/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rinse-and-repeat-with-tdd</feedburner:origLink></item>
		<item>
		<title>Five important trends on the enterprise architect’s radar</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/W7M_qgim3Ks/</link>
		<comments>http://blog.dhananjaynene.com/2009/11/five-important-trends-on-the-enterprise-architects-radar/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 09:19:02 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[polyglotism]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=912</guid>
		<description><![CDATA[It is no secret that the internet architectures are influencing enterprise architectures. This post attempts to summarise some of the recent trends in the internet space, which seem to be carrying some momentum sufficient enough to influence the enterprise. So without further ado, these trends are : REST : The Representational State Transfer architecture style [...]]]></description>
			<content:encoded><![CDATA[<p>It is no secret that the internet architectures are influencing enterprise architectures. This post attempts to summarise some of the recent trends in the internet space, which seem to be carrying some momentum sufficient enough to influence the enterprise. So without further ado, these trends are :</p>
<ol>
<li><strong>REST :</strong> The <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">Representational State Transfer</a> architecture style builds on the essential elements of those constructs which made the internet so globally scalable. A detailed explanation of the rationale and strengths of REST are completely beyond the scope of this article. If your job requires you to be continuously aware of emergent trends and whether they fit your enterprise architecture needs &#8211; this is the one must explore trend.
<p><em>Impact : </em> Web based architectures, Service Oriented Architectures, wide availability and immediate usability of data and processing requests (resources) through simple HTTP URIs and minimal integration effort</li>
<li><strong>Interoperable Cloud :</strong> The interoperable cloud is the ability to create a private cloud and also leverage a public cloud. This has been made possible by offerings such as the <a href="http://www.ubuntu.com/cloud">Ubuntu Enterprise Cloud</a> which allows you to build a private cloud or use a public cloud such as <a href="http://aws.amazon.com/ec2/">Amazon EC2</a> while being able to access them using the same set of APIs thanks to open source efforts such as <a href="http://open.eucalyptus.com/">Eucalyptus</a>. This allows you the flexibility of initially using either a private or public cloud and then subsequently shifting to the other, or being able to use both simultaneously.
<p><em>Impact : </em> Large servers vs cluster of commodity servers, virtualisation, elastic deployments, flexible hardware procurement / provisioning, infrastructure management in organisational hierarchy.</li>
<li><strong>NoSQL :</strong> While I am unhappy with the name, it has stuck. This refers to a set of options now available to store your data unconstrained by many RDBMS requirements (eg. flexible schema, key value pairs etc.). Some of the databases also allow you to store data in a distributed manner over a number of servers with an intent to support high availability in write intense scenarios even as they may require you to move towards eventual consistency. These options increase your manouverability / flexibility as an architect even as they require you to meet a different set of challenges.
<p><em>Impact :</em> Relational databases, data storage strategies, data distribution strategies, vertical vs. horizontal scalability, transactionalisation, consistency and availability</li>
<li><strong>Polyglotism :</strong> Developer costs now occupy an increasing percentage of total costs, development time is being an increasingly dominant factor for time to market, and ability of software to change and adapt quickly to newer demands is now a critical success metric. One of the solutions is to write different parts of the software in a different languages most appropriately suited for concise and rapid coding as well as supporting quick reaction changes to each part appropriately. Thus it is conceivable to have some of the business rules written in a dsl written using jruby and some of the algorithms written in clojure in a software built on the JEE platform.
<p><em>Impact :</em>Development culture and processes, minimum developer skill and scalability, risk management for managing required vs. available skills.</li>
<li><strong>Decentralised processing :</strong> Thanks to many developments which are leading to increasingly distributed processing including REST and NoSQL, applications will need to be a set of collaborating network based components (we&#8217;ve heard this before with distributed objects as well). However especially given some of the lesser guarantees that such architectures can provide around immediate guaranteed processing, latency issues, distributed control and asynchronous processing, a particular piece of business logic may get satisfied in a staggered fashion across a number of collaborating components. This may increase challenges in terms of currency of available data even as it helps actually deliver on the vision of distributed objects and simplifies individual component development. While asynchronous capabilities such as those supported by MQ series and the like have been used in the enterprise for ages, I do anticipate increasing use of lighter messaging constructs such as <a href="http://en.wikipedia.org/wiki/PubSubHubbub">PubSubHubbub</a> within the enterprise.
<p><em>Impact :</em> Application partitioning, network based components, difficulty in supporting fully synchronous workflows.</li>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=W7M_qgim3Ks:740DIcOFQ_o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=W7M_qgim3Ks:740DIcOFQ_o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=W7M_qgim3Ks:740DIcOFQ_o:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=W7M_qgim3Ks:740DIcOFQ_o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=W7M_qgim3Ks:740DIcOFQ_o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=W7M_qgim3Ks:740DIcOFQ_o:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/W7M_qgim3Ks" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/11/five-important-trends-on-the-enterprise-architects-radar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/11/five-important-trends-on-the-enterprise-architects-radar/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=five-important-trends-on-the-enterprise-architects-radar</feedburner:origLink></item>
		<item>
		<title>Service Oriented Architecture is primarily about business and not technology. Bollocks!</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/d_mJprNs8Ak/</link>
		<comments>http://blog.dhananjaynene.com/2009/10/service-oriented-architecture-is-primarily-about-business-and-not-technology.-bollocks/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 10:56:51 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[soa]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=902</guid>
		<description><![CDATA[There&#8217;s quite a few times I&#8217;ve heard / read a gross oversimplification of architecture in reference to business and technology. And while I believe I understand the &#8216;essential cause&#8217; which drives such a simplification, I&#8217;ve often felt quite frustrated at the resultant impression thats provided by such a simplification. In many ways and forms, it [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s quite a few times I&#8217;ve heard / read a gross oversimplification of architecture in reference to business and technology. And while I believe I understand the &#8216;essential cause&#8217; which drives such a simplification, I&#8217;ve often felt quite frustrated at the resultant impression thats provided by such a simplification. In many ways and forms, it boils down to the statement (not exactly the same since I&#8217;m not quoting directly), quite similar to the one below :</p>
<p><strong><em>Service Oriented Architecture is primarily about business and not technology</em></strong></p>
<p>This also reflected in the recent <a href="http://soa-manifesto.org/">SOA Manifesto</a> which states as its very first described value :</p>
<p><strong><em>Business value over technical strategy</em></strong></p>
<p>Allow me to straight away start picking some holes into this :</p>
<ol>
<li>Anything that a business does &#8211; whether it is soa, software architecture, building architecture or simple plant and machinery design, to the extent (which is exactly 100%), technology serves the business goals, all technology activities (and non-technology as well) are at the end of the day about achieving business objectives and therefore about business. So why single out architecture? And even more so why single out SOA?</li>
<li>Architecture is also about business. But its not the same as saying its primarily about business and not so much about technology. For a moment lets step away from Software/Hardware Architecture and look at Building Construction Architecture. The legendary creation of Ayn Rand &#8211; Howard Roark, for all his eccentricities and seemingly portrayed egocentric and egotistic behaviour did meet the test of business objectives to the extent of making the residents of his creations extremely satisfied. And at no point would you gather the impression that he in any manner put construction technology to any secondary position to his business context and objectives. At the end of the day thats what architecture is. It is not about making one of business or technology more important than or subservient to other. Its about effectively mapping the two to provide a strong technology solution appropriate to the business needs. </li>
</ol>
<p>I suspect one of the important causes here is that people have forgotten that the A in SOA stands for architecture, and therefore shorn of architecture, business and technology can be seen to be competing in a non win-win form. </p>
<p>So if SOA stands for Service Oriented <strong><em>Architecture</em></strong>, then I must submit that architecture is the art of getting the two working together. And I am of the opinion that an exercise suggesting one is more important than other is an exercise in a field unrelated to architecture. I suspect many practicing software architects will agree with this. I suspect Ayn Rand wouldn&#8217;t disagree as well.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=d_mJprNs8Ak:YCxpklrekkI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=d_mJprNs8Ak:YCxpklrekkI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=d_mJprNs8Ak:YCxpklrekkI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=d_mJprNs8Ak:YCxpklrekkI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=d_mJprNs8Ak:YCxpklrekkI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=d_mJprNs8Ak:YCxpklrekkI:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/d_mJprNs8Ak" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/10/service-oriented-architecture-is-primarily-about-business-and-not-technology.-bollocks/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/10/service-oriented-architecture-is-primarily-about-business-and-not-technology.-bollocks/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=service-oriented-architecture-is-primarily-about-business-and-not-technology.-bollocks</feedburner:origLink></item>
		<item>
		<title>Stop calling me NoSQL</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/lIqzzGZmSrI/</link>
		<comments>http://blog.dhananjaynene.com/2009/10/stop-calling-me-nosql/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 23:26:09 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[natural persistence]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[schemaless databases]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=884</guid>
		<description><![CDATA[Dear Reader, Apologies for sending this note to you completely unannounced and out of the blue. However I find myself in a peculiar situation of having a very weird name being dumped upon me. While I am indifferent to the name per se, I am greatly pained as I realise that it is a completely [...]]]></description>
			<content:encoded><![CDATA[<p>Dear Reader,</p>
<p>Apologies for sending this note to you completely unannounced and out of the blue. However I find myself in a peculiar situation of having a very weird name being dumped upon me. While I am indifferent to the name per se, I am greatly pained as I realise that it is a completely inappropriate name. What is even more confounding is the very bunch of people who have happily assigned me the name and continue to popularise it belong to that class of people some of whom actually are extremely particular about accurate nomenclature and have no hesitation in creating a 100 letter class or function name by concatenating 20 words just to make sure the name is unambiguous and conveys the intent clearly. </p>
<p>Ahh.. but I digress and impose upon you without introducing myself adequately first. I am a data storage style. I am not new, but lately far too many a software engineer have started taking a liking for me. Ever since I have been around, I have with great amounts of jealousy watched my cousin the RDBMS being courted by the finest of engineers (in all honesty there were some fine engineers interested in me too, but far too few compared to my cousin). But lately multiple concurrent developments have made a fair amount of attention come my way too. </p>
<p>You see unlike RDBMS, I don&#8217;t require that data be clearly split into tables, columns and rows. I can work with data the way it is most naturally represented. As a tree of individual data fields, lists, arrays, dictionaries etc. Also I do not require that you always clearly define each and every possible schema element before being able to store data corresponding to the schema. I can happily accept a schema dynamically or even work without a schema. Some of my early forms were based on key value pairs stored as B-Trees (eg. Berkeley DB). Over the years people have figured out ways to represent the data as a set of decomposed document elements, store data spread across a cluster, replicate it for better availability and fault tolerance, and even perform post storage processing tasks using map-reduce sequences. But really what separates me from my cousin and other storage systems is that I don&#8217;t make demands on the data &#8211; I take it in its naturally found form and then store it, replicate it, slice it, dice it and glean information out of it. And therein lies my true identity &#8211; I will work with data the way the data is best represented with all its arbitrary inconsistencies and inabilities to always clearly specify a constraining schema. And the engineers who&#8217;ve spent time with me seem to have enjoyed it quite a bit. </p>
<p>But the horror of it &#8211; they gave me a completely inappropriate moniker &#8211; &#8216;NoSQL&#8217;. First and foremost I exist to promote a storage style and thats what identifies me. I work with data in its natural and arbitrary forms. Therefore to make it seem like I represent a lack of something else is utterly missing the point. The SQL in NoSQL stands for Structured Query Language, which depends upon Fixed Structure Relational Data. Since I change the very nature of the data being stored, that SQL is not required or relevant is automatic and inconsequential. </p>
<p>Its like calling a under-the-ocean-mountain_range as NoIgloo. Its dead obvious igloos will not be found there. But calling that mountain range NoIgloo is a big disservice to visitors. You use that as a marketing term, attract people, then tell them that NoIgloo actually has nothing to do with Igloos &#8211; its got to do with mountains and oceans, and that they need to first unwind all the confusion they created in their minds due to NoIgloo and then go through a phase of reunderstanding mountains and oceans. And while they came prepared for a possibly warmer place given the name NoIgloo &#8211; it actually is a wet place so they need to again change their garments and equipment for the journey. A wholely avoidable situation.</p>
<p><em>Update: <a href="http://twitter.com/boorad">Brad Anderson</a> pointed out this interesting post <a href="http://voodootikigod.com/nosql-a-modest-proposal">NoSQL: A Modest Proposal</a> which traces the genesis of my name which leaves me very very disappointed. Almost seems to suggest that people are flocking together and naming me not based on something inherently powerful about me &#8211; but as a mechanism to demonise my cousin RDBMS. This is most unfortunate, since we actually end up being useful in very different situations and more often than not are likely to complement each other rather than compete with each other. I do hope a better moniker does prevail over time</em> </p>
<p>What I would like is to see a better / more appropriate name for me. Hmm .. call me free form storage, natural persistence or flexi schema storage or perhaps something else even more appropriate (this blog owner prefers &#8220;natural persistence&#8221;). Each of these conveys far more about me far more accurately than NoSQL does. Basically please please call me something better than NoSQL. So can I request you to carry forward my plea by further forwarding and retweeting this to your friends and ask them how they can so callously call me by such a silly name when they take the utmost precautions in properly naming their classes and methods. Plead with them to stop doing this and please work with others to give me a better name. I think it will cause less confusion over the coming months and years, and the field of software shall recover its glorious tradition of maintaining precision in communication by using accurate naming.</p>
<p>Sincerely,<br />
The one who doesn&#8217;t want to be called NoSQL</p>
<p>PS : As a background to this there was an interesting conversation earlier today between this blog owner <a href="http://twitter.com/dnene">dnene</a> and <a href="http://twitter.com/KentBeck">Kent Beck</a> on twitter, where Kent so kindly and graciously helped carry forward the thought process of helping identify my essential characteristics, and it is in no small part, thanks to this conversation that I was able to articulate myself and my grief. I reproduce that conversation below. (<em>Update: though in all likelihood Kent&#8217;s intent was to help clarify the thought rather than contest the names. In hindsight, it makes sense to ask for permission to reproduce conversations .. even when such are on the public twitter stream &#8211; something that wasn&#8217;t done in this case. <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  </em>)</p>
<table cellspacing="3" cellpadding="3">
<tr>
<th>Twitter ID</th>
<th>Tweet / Message</th>
</tr>
<tr>
<td valign="top">dnene</td>
<td>NoSQL is such an inappropriate name. NoTables at least makes a little more sense.</td>
</tr>
<tr>
<td valign="top">KentBeck</td>
<td>@dnene but what would nosql be called if you wanted to say something positive about it?</td>
</tr>
<tr>
<td valign="top">dnene</td>
<td>@KentBeck Thats a great question .. still thinking .. best thought so far &#8211; FlexiStore (though not good enough yet <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  )</td>
</tr>
<tr>
<td valign="top">KentBeck</td>
<td>@dnene what can you do with a nosql store that you can&#8217;t do with an sql database? why would you be excited to use one?</td>
</tr>
<tr>
<td rowspan="2" valign="top">dnene</td>
<td>@KentBeck I see where u r going with this (a) unconstrained &#038; composite storage (b) store resources not records (c) shard/scale horizontally</td>
</tr>
<tr>
<td>.@KentBeck I think there is a merit in attempting to define nosql in terms of what it is rather than what it isn&#8217;t</td>
</tr>
<tr>
<td valign="top">KentBeck</td>
<td>@dnene there are many more people confused about what datastore to use than who hate sql. the positive approach appeals to the former.</td>
</tr>
<tr>
<td valign="top">dnene</td>
<td>@KentBeck Agreed .. and I&#8217;m aware of many more who wonder why we need a different datastore than the RDBMSs. NoSQL as a name doesn&#8217;t help.</td>
</tr>
<tr>
<td valign="top">KentBeck</td>
<td>@dnene well, why *do* we need a different data store?</td>
</tr>
<tr>
<td rowspan="3" valign="top">dnene</td>
<td>@KentBeck Primary Need : We need support for flexible/arbitrary schemas with complex depths &#8211; RDBMSs don&#8217;t dance well in this space.</td>
</tr>
<tr>
<td>@KentBeck Secondary Need : Support for deferred processing required for analytics (eg. Map/Reduce). RDBMS don&#8217;t do too bad a job here</td>
</tr>
<tr>
<td>@KentBeck Tertiary Need (not one that I&#8217;ve felt strongly yet) : Distributed and horizontally scalable storage on commoditized h/w.</td>
</tr>
<tr>
<td valign="top">KentBeck</td>
<td>@dnene it seems like you&#8217;re looking for realistically structured data, not data twisted to fit a formula convenient for mathematicians.</td>
</tr>
<tr>
<td rowspan="2" valign="top">dnene</td>
<td>@KentBeck Yes.. thats it! I&#8217;m looking for realistically or naturally structured data storage / persistence. Rocks compared to the term nosql</td>
</tr>
<tr>
<td>@KentBeck Wonder if the term arbitrarily structured makes sense as well. This has been one heck of a conversation/Q&#038;A so far +1:)</td>
</tr>
<tr>
<td valign="top">KentBeck</td>
<td>@dnene glad you found it helpful. you get bonus points if the opposite of the name you pick is unattractive, a la &#8220;structured programming&#8221;</td>
</tr>
</table>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=lIqzzGZmSrI:sFDOHza25Ew:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=lIqzzGZmSrI:sFDOHza25Ew:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=lIqzzGZmSrI:sFDOHza25Ew:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=lIqzzGZmSrI:sFDOHza25Ew:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=lIqzzGZmSrI:sFDOHza25Ew:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=lIqzzGZmSrI:sFDOHza25Ew:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/lIqzzGZmSrI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/10/stop-calling-me-nosql/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/10/stop-calling-me-nosql/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=stop-calling-me-nosql</feedburner:origLink></item>
		<item>
		<title>NoSQL – A fluid architecture in transition</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/7R4sW1986Xo/</link>
		<comments>http://blog.dhananjaynene.com/2009/10/nosql-a-fluid-architecture-in-transition/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 18:21:14 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[couchdb]]></category>
		<category><![CDATA[lightcloud]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[riak]]></category>
		<category><![CDATA[tokyotyrant]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=867</guid>
		<description><![CDATA[Lot of talk about NoSQL. Much of it well deserved. And while lot of the excitement around it is well understood by those in the know, some of it may actually be confusing to those who are relatively new to the matter. This post is actually for the latter group &#8211; not to argue for [...]]]></description>
			<content:encoded><![CDATA[<p>Lot of talk about NoSQL. Much of it well deserved. And while lot of the excitement around it is well understood by those in the know, some of it may actually be confusing to those who are relatively new to the matter. This post is actually for the latter group &#8211; not to argue for or against NoSQL &#8211; just to put it in perspective.</p>
<p><strong>What is NoSQL : </strong>Some of the characteristics shared by most if not all the NoSQL engines are as follows :</p>
<ol>
<li><strong>Schemaless or Hierarchical Schema Storage</strong> NoSQL assumes at its very basis a schemaless or a hierarchichal schema storage system. In most cases this consists of a simple key value pair storage. While some storage engines excel at storing small values (LightCloud/Tokyo Cabinet), some are strong at storing large documents (CouchDB). </li>
<li><strong>Distributed storage :</strong> This is one of the driving forces of NoSQL growth, though not a distinguishing characteristic of NoSQL. One of the areas these storage systems separate themselves from RDBMS&#8217;s is their ability to allow better horizontal scalability. This varies from the simple master-master replication for MongoDB, to multi node sharding using consistent hashing with LightCloud (a la memcached) to a multiple master eventual consistency model of Riak. The basic premise in using some of the NoSQL engines is that storage will scale horizontally.</li>
<li><strong>Support for deferred processing :</strong>Many of these engines allow for some degree of deferred processing. Whether this be simple lua scripting in case of LightCloud or map-reduce scripts in case of CouchDB, the general assumption is that some amount of latency in computation times is acceptable, and some of the computations (especially related to analytics based views) will be performed post storage.</li>
<li><strong>Eventual Consistency :</strong> This may seem like a necessary feature of all NoSQL storage systems but it isn&#8217;t. While clearly some such as CouchDB (in terms of its map-reduce views) and Riak are better placed for supporting and implementing eventual consistency, it is quite feasible to use others such as LightCloud or MongoDB to implement immediate consistency using a single master-master pair. Suffice to note that eventual consistency is not a necessary side effect of using a NoSQL storage system, though it wouldn&#8217;t be incompatible for the two to work together. </li>
</ol>
<p>But the points I would really like to emphasize are :</p>
<ul>
<li><strong>NoSQL is not a direct competitor to RDBMS/SQL :</strong> It is actually a solution to many use cases where using RDBMS was perhaps a poor fit. Thus the decision for an architect is not which of the two competing options (RDBMS or NoSQL) <em>Update: <del datetime="2009-10-21T20:11:10+00:00">one should select</del><ins datetime="2009-10-21T20:11:10+00:00">should be the preferred standard storage strategy</ins></em>, &#8211; it simply is which one is the more appropriate storage system for the application under consideration.</li>
<li><strong>NoSQL is still at a fluid stage of its development : </strong> All the NoSQL storage systems (but for LightCloud/Tokyo Tyrant) are still being quite actively developed. These have not reached v 1.0 <em>(Update: MongoDB is at v 1.1)</em> and it is likely that some time will pass before any of these get beyond the beta and release candidate stage and get a 1.0 in-production stamp. While there is a lot of interest, there still is a substantial amount of experimentation in terms of the right feature sets leading to differently focused developments in different storage systems. To an architect this represents an interesting challenge. I think the way to approach this right now is to not use these in mission critical (eg. life or health impacting) systems, and to focus on reasonable expectation management in terms of ensuring the right kind of SLAs around their availability (simply because many of these haven&#8217;t yet been put to intense use in production the way say an Oracle or MySQL have been). This is not an attempt to spread &#8220;FUD&#8221; about NoSQL &#8211; far from it it is an exercise in setting appropriate expectations. i would also recommend that it would be appropriate to evaluate the available NoSQL choices only when reasonable SLAs can be worked out for their usage. It is certainly preferred to using NoSQLs rather than using RDBMS&#8217;s in an inappropriate manner (large objects serialised into BLOBs or into name-value pair tables). However, I would suggest that you do not deeply bind yourself into a particular NoSQL engine. The future development of most of the storage systems is still unknown to a certain extent, as is the future landscape including any shakeouts. Should one recommend usage of a NoSQL engine &#8211; it is important to have a clear plan for switching over to an alternative engine should a need arise in the future. While this is easier said than done, deciding the appropriate level of abstraction to use (ie. code to the API directly vs. use a layer of abstraction for engine independence) is best left to designer / architect to dwell upon.</li>
</ul>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7R4sW1986Xo:LRIrmzvjZ3k:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7R4sW1986Xo:LRIrmzvjZ3k:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=7R4sW1986Xo:LRIrmzvjZ3k:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7R4sW1986Xo:LRIrmzvjZ3k:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=7R4sW1986Xo:LRIrmzvjZ3k:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7R4sW1986Xo:LRIrmzvjZ3k:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/7R4sW1986Xo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/10/nosql-a-fluid-architecture-in-transition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/10/nosql-a-fluid-architecture-in-transition/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=nosql-a-fluid-architecture-in-transition</feedburner:origLink></item>
		<item>
		<title>Configuring a secure Ubuntu Linux Virtual Private Server</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/rDQBoHSlFSg/</link>
		<comments>http://blog.dhananjaynene.com/2009/10/configuring-a-secure-ubuntu-linux-virtual-private-server/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 13:56:20 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vps]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=852</guid>
		<description><![CDATA[This post is based on my notes for an initial configuration for an Ubuntu 9.04 Virtual Private Server with a focus on security. At that time I searched for a number of references on security, and while I have not kept the note of all their URLs, most of what I write below is as [...]]]></description>
			<content:encoded><![CDATA[<p>This post is based on my notes for an initial configuration for an Ubuntu 9.04 Virtual Private Server with a focus on security. At that time I searched for a number of references on security, and while I have not kept the note of all their URLs, most of what I write below is as a result of other documents even though I cannot specifically cite them (in other words, there is little originality except perhaps for attempting to cover the entire gamut of configuration activities into one article).</p>
<p>Keep in mind that these steps are based on my notes which might be a little incomplete especially around the part where acidbase is installed.</p>
<ul>
<li><a href="#InitialConfig">Initial Configuration</a> : Basic configuration when getting started up.</li>
<li><a href="#BasicSecurity">Setting up basic security</a> : Basic Security configuration</li>
<li><a href="#RootkitDetection">Setting up rootkit detection</a> : Setting up rootkit detection</li>
<li><a href="#BastilleSetup">Setting up Bastille</a> : Setting up Bastille</li>
<li><a href="#LampStack">Setting up the lamp stack</a> : Set up the LAMP stack including mysql and apache</li>
<li><a href="#SnortSetup">Setting up Snort and acidbase</a> : Configure Intrusion detection using Snort and Acidbase.</li>
<li><a href="#FileIntegrity">Setting up File Integrity using AIDE </a> : Setting up File integrity checks using AIDE</li>
</ul>
<p><a name="InitialConfig"></a></p>
<h2> Initial Configuration</h2>
<p>These steps cover the initial setup of a server</p>
<h3> Setup the hostname </h3>
<p>Lets say the hostname we want to setup is <em>vps</em>.</p>
<div class="console">
$ echo &#8220;vps.mydomain.com&#8221; > /etc/hostname<br />
$ hostname -F /etc/hostname
</div>
<p>Now update the <em>/etc/hosts</em> file to reflect the hostname and the fully qualified domain name<br />
<em>Replace 12.34.56.78 with the IP address of your host</em></p>
<div class="console">
127.0.0.1       localhost.localdomain  localhost<br />
12.34.56.78     vps.mydomain.com vps
</div>
<h3> Updating the ubuntu repositories </h3>
<p>You will need to update your ubuntu repositories to include jaunty-updates and universe repositories. This is so that you may install additional packages as required from these repositories as well. In my case, the earlier version of the file <em>/etc/apt/sources.list</em> was as follows.</p>
<p>However please note, that repository selection and its update strategy may be linked to your company or application strategy. Please make sure these steps are consistent with your policy. If not, kindly adapt consistent with your team / organisations policy. Also instead of us.archive.ubuntu.com, you may find other country specific server names. In that case you may want to continue to use the other server name as already listed in your file.</p>
<div class="console">
deb http://us.archive.ubuntu.com/ubuntu/ jaunty main restricted<br />
deb-src http://us.archive.ubuntu.com/ubuntu/ jaunty main restricted</p>
<p>deb http://security.ubuntu.com/ubuntu jaunty-security main restricted<br />
deb-src http://security.ubuntu.com/ubuntu jaunty-security main restricted
</p></div>
<p>Upon adding jaunty-updates and the universe repositories, the resultant file is as follows.</p>
<div class="console">
deb http://us.archive.ubuntu.com/ubuntu/ jaunty main restricted universe<br />
deb-src http://us.archive.ubuntu.com/ubuntu/ jaunty main restricted universe</p>
<p>deb http://security.ubuntu.com/ubuntu jaunty-security main restricted universe<br />
deb-src http://security.ubuntu.com/ubuntu jaunty-security main restricted universe</p>
<p>deb http://us.archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe<br />
deb-src http://us.archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe
</p></div>
<p>Now update the sources. This will scan all the repositories</p>
<div class="console">
$ sudo apt-get update
</div>
<p>Finally upgrade ie. replace any existing packages which have a newer upgrade</p>
<div class="console">
$ sudo apt-get upgrade
</div>
<h3> Download the language pack </h3>
<p>To add the necessary for the preferred language of your choice add the appropriate language pack. In my case I add support for english (en)</p>
<div class="console">
$ sudo apt-get install language-pack-en
</div>
<h3> Set the timezone </h3>
<p>Set the timezone of the server. You may choose to set it based on server location, or typical user location or to UTC.</p>
<div class="console">
$ dpkg-reconfigure tzdata
</div>
<p>That will start a small app, from which you can select the timezone. I selected <em>None of the Above</em> which offered me a choice of timezones based on UTC offsets and subsequently selected <em>UTC</em>.</p>
<h3> Setting up Mail sending </h3>
<p>I do not need this VPS to act as a mail server. However I do need to have capabilities to send email from this machine. Many unix tools routinely assume the existence of sendmail or equivalent MTA. However that is an overkill in this context. So we shall not be installing sendmail or postfix or exim or any other equivalent. Instead we shall configure this server to be only able to send out mail using an SMTP account on another mail server. For this we shall install a tool called mailx. <em>Note: If you have mailx already installed through another ubuntu package called mailutils, you may either continue with the same (in which case you will need to configure the remainder of the mail stack correspondingly eg. sendmail) or remove mailutils and add heirloom-mailx</em></p>
<div class="console">
$ sudo apt-get install heirloom-mailx
</div>
<p>We shall also configure a global configuration for sending out mail. In my case its all right to always send mail using only one account irrespective of the process or user who is sending it.</p>
<div class="console">
$ sudo vi /etc/nail.rc
</div>
<p>Note that in the above configuration, we shall be placing the mail account password in clear text. Make sure it is a mail account you do not use for any other purposes and that its password is not the same as used for any other purposes. Now enter the following as contents of the <em>/etc/nail.rc</em> file. Obviously change the relevant fields to appropriate values. Note that this file is configured for sending mail via gmail. You may need to configure it differently based on your own SMTP configurations.</p>
<div class="console">
set smtp-use-starttls<br />
set from=my_user_id@gmail.com<br />
set smtp=smtp.gmail.com:587<br />
set smtp-auth-user=my_user_id@gmail.com<br />
set auth-login=my_user_id@gmail.com<br />
set smtp-auth-password=my_password
</div>
<p>You can try testing whether this got set up successfully. Enter the following (replace youremailid@youremaildomain.com by the email id where you would like the mail to be sent to)</p>
<div class="console">
$ mail youremailid@youremaildomain.com<br />
Subject: This is a test mail<br />
Hello<br />
.
</div>
<p><a name="BasicSecurity"></a></p>
<h2>Basic Security</h2>
<p>In this section we shall make some basic configuration changes with a view to enhance the system security.</p>
<h3> Mounting the shared memory as read only </h3>
<p>Open and edit the file /etc/fstab to add an entry to mount shared memory in read only mode. The reason we do it is because many exploits use shared memory to attack other running services.</p>
<p>If you have a good reason to make shared memory writeable skip this step.</p>
<div class="console">
$ vi /etc/fstab
</div>
<p>Now add the following line at the end of the file</p>
<div class="console">
tmpfs           /dev/shm        tmpfs   defaults,ro     0       0
</div>
<h3> Tightening the passwords </h3>
<p>One of the easiest exploits is to attempt a brute force login using dictionary based attacks. In order to ensure strong ie. non-guessable passwords we shall update the password checking policy so that it allows only strong passwords. A simple way to ensure that is to ensure a reasonable minimum length and to ensure multiple character classes.</p>
<p>First lets install a new pam authentication module pam_cracklib. To install the same run the following</p>
<div class="console">
$ sudo apt-get install libpam-cracklib
</div>
<p>Answer &#8216;Y&#8217; to the prompt it asks for regarding continuing.</p>
<p><em>Note: if you did not add the universe repository to your sources.list file, you will not be able to install libpam-cracklib. In that case you will need to skip this step.</em></p>
<p>This should&#8217;ve resulted in the file <em>etc/pam.d/common-password</em> having an entry for pam_cracklib.so and pam_unix.so. Update the pam_cracklib.so entry to add one more requirement ie. <em>minclass=4</em>.</p>
<p>In my case, the resultant two lines in <em>/etc/pam.d/common-password</em> are as follows. Note that I added the minclass=4 clause manually.</p>
<div class="console">
password        requisite                       pam_cracklib.so retry=3 minlen=8 difok=3 minclass=4<br />
password        [success=1 default=ignore]      pam_unix.so obscure use_authtok try_first_pass sha512
</div>
<p>There. You now have a strong password scheme which will conduct a whole range of password checks in addition to ensuring that the password has a minimum length of 8 and each new password has at least one each of the four character classes. The four character classes are lower_case, upper_case, digit and special_characters (the last one being any non alpha-numeric character)</p>
<h3> Creating the first user </h3>
<p>Note: if you have already created at least one more non root user this step is not required. We are primarily creating the new user so that we shall eventually allow sudo and remote ssh login privileges to the user and disable remote ssh privileges for the root user.</p>
<p>Setup the first new user. One of the reasons you should create a new user is so that it will afford you the ability to allow him to perform root actions through sudo, and thus subsequently allow you to disable root access over ssh. By default when one creates a new user, another group gets created with the same name as well. In this case we shall create a new group &#8220;<em>dev</em>&#8221; and then create a new user associated with that group &#8220;<em>someuser</em>&#8220;. Use the groupname and the username as you would like to setup when executing the commands below. In the commands below we create a new home directory for the user, associate the <em>/bin/bash</em> shell with his account instead of the default <em>/bin/sh</em>, (I just prefer bash to the plain sh) and finally set the password for him.</p>
<div class="console">
$ groupadd dev<br />
$ mkdir /home/someuser<br />
$ useradd -d /home/someuser -s /bin/bash -g dev someuser<br />
$ chown someuser.dev /home/someuser<br />
$ passwd someuser
</div>
<p>We shall also create the .ssh directory for the user which we shall be using later</p>
<div class="console">
$ mkdir /home/someuser/.ssh<br />
$ chmod 700 /home/someuser/.ssh<br />
$ touch /home/someuser/.ssh/authorized_keys<br />
$ chmod 600 /home/someuser/.ssh/authorized_keys<br />
$ chown -R someuser.dev /home/someuser
</div>
<p>Now we shall create the keypair for the user to log in to the host remotely. Note that if you are going to do this for multiple users, then you might want to have each user run the next step locally and then copy over his public key onto the server before continuing to the ssh tightening operations described later.</p>
<p>The user should do the following on his <em>local workstation from which he is most frequently likely to connect to the server (not the server that we are hardening)</em>.</p>
<p><em>Note: the part after -C in ssh-keygen is just a comment to identify the keys &#8211; enter something to identify the user and his machine.</em><br />
Also make sure not to keep the passphrase blank though ssh-keygen will allow a blank passphrase. The reason is that if the user&#8217;s local machine is compromised the attacker can then get an easy access to the server being hardened.</p>
<p><em>change someuser and some.host.com below based on the user id and vps name correspondingly</em></p>
<div class="console">
$ mkdir ~/.ssh<br />
$ ssh-keygen -t dsa -b 1024 -C &#8220;some user on his desktop&#8221;<br />
$ scp ~/.ssh/id_dsa.pub someuser@some.host.com:/home/someuser/.ssh/someuser.pub
</div>
<p>Now the user should himself ssh to the remote server and on the remote server move his public key into the <em>authorized_keys</em> file. So execute the following command after being connected to the VPS</p>
<div class="console">
$ cd .ssh<br />
$ cat someuser.pub >> authorized_keys<br />
$ rm someuser.pub
</div>
<p>At this stage the user can disconnect from the VPS and attempt to reconnect using ssh. If all works well, he should get connected to the vps in a manner where it does not prompt him for a password but instead he does get prompted for the passphrase to his private key (assuming he did set one).</p>
<p>This stage of updating the authorized_key file can also be performed by an administrative user / root once we later reconfigure ssh to only allow public key based logins.</p>
<h3> Enabling the user to perform sudo operations </h3>
<p>We shall enable any group who belongs to the group &#8216;<em>admin</em>&#8216; to be able to conduct root operations through using sudo. </p>
<p>First create a group &#8216;<em>admin</em>&#8216;. subsequently associate the user with that group as well. Note : For best security ensure you allow associate only a very small number of users with the &#8216;admin&#8217; group since that will effectively allow them control over the whole machine (assuming you setup the privileges as I subsequently describe below).</p>
<div class="console">
$ groupadd admin<br />
$ adduser someuser admin
</div>
<p>Now we shall enable any user who belongs to the admin group to perform root actions by using sudo. To edit the sudo policy file do the following</p>
<div class="console">
$ sudo visudo
</div>
<p>At the end of the file which is now opened up &#8211; add the following line</p>
<div class="console">
%admin ALL=(ALL) ALL
</div>
<p>Note this grants all superuser privileges to the users who belongs to admin group when conducting operations using sudo. You can use the sudo policy configurations to set up far more fine grained set of privileges, but thats beyond the scope of this document.</p>
<p>To test whether the configuration worked successfully, you can login as <em>someuser</em> and execute the following command.</p>
<div class="console">
$ sudo cat /etc/shadow
</div>
<h3> Tightening up ssh </h3>
<p>To create the group and associate the users with them perform the following command (use the appropriate username instead of someuser for each user who you would like to allow SSH access).</p>
<div class="console">
sudo addgroup sshlogin<br />
sudo adduser someuser sshlogin
</div>
<p><span id="more-852"></span><br />
Now that we have at least one user id which can conduct root operations using <em>sudo</em>, its time to disable root login from ssh. Go open the file <em>/etc/ssh/sshd_config</em>. Make the following changes</p>
<p>This one disables root login for ssh.<br />
<em>PermitRootLogin yes</em> to <em>PermitRootLogin no</em></p>
<p>Adding the following line allows only users of a particular group to login. <em>Note: if your user count is small, you could use <em>AllowUsers</em> instead</em>. We shall be separately creating the group and associating the users with the group.<br />
<em>AllowGroups sshlogin</em></p>
<p>This change reduces the login grace time (time before a user needs to login after making the ssh login request). This is to allow better protection to sshd against DOS or brute force attacks.<br />
<em>LoginGraceTime 20</em> to <em>LoginGraceTime 20</em></p>
<p>This changes the port number that <em>sshd</em> listens on from the default 22. Changing the default port takes away the ability of an attacker to easily guess the port on which to attempt to penetrate the system via ssh.<br />
<em>Port 22</em> to <em>Port 9999</em> (or any other suitable number) </p>
<p>This change disables X11Forwarding over the SSH connection. It will result in you not being able to run X11 GUI applications remotely. If you need that flexibility, do not make this change<br />
<em>X11Forwarding yes</em> to <em>X11Forwarding no</em></p>
<p>The next change disables password authentication (thus allowing only users with their public key being stored in the corresponding authorized_keys folder to connect using ssh). Thus passwords, which need to be transferred to the server in clear text no longer are a valid authentication mechanism. The only available choice is public key based authentication.<br />
<em>PasswordAuthentication yes</em> to <em>PasswordAuthentication No</em></p>
<p>The next change disables password authentication (thus allowing only users with their public key being stored in the corresponding authorized_keys folder to connect using ssh). Thus passwords, which need to be transferred to the server in clear text no longer are a valid authentication mechanism. The only available choice is public key based authentication.<br />
<em>PasswordAuthentication yes</em> to <em>PasswordAuthentication No</em><br />
<em>UsePAM yes</em> to <em>UsePAM no</em></p>
<p>The following change of uncommenting the banner allows a welcome message (not really a welcome one <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) to be displayed to SSH logins. It does not improve any aspect of the physical security but is more from a legal notice perspective.<br />
<em>#Banner /etc/issue.net</em> to <em>Banner /etc/issue.net</em></p>
<p>Now go update the contents of the file <em>/etc/issue.net</em> to something similar to following</p>
<div class="console">
***************************************************************************<br />
                                                        NOTICE TO USERS</p>
<p>This computer system is the private property of its owner, whether<br />
individual, corporate or government.  It is for authorized use only.<br />
Users (authorized or unauthorized) have no explicit or implicit<br />
expectation of privacy.</p>
<p>Any or all uses of this system and all files on this system may be<br />
intercepted, monitored, recorded, copied, audited, inspected, and<br />
disclosed to your employer, to authorized site, government, and law<br />
enforcement personnel, as well as authorized officials of government<br />
agencies, both domestic and foreign.</p>
<p>By using this system, the user consents to such interception, monitoring,<br />
recording, copying, auditing, inspection, and disclosure at the<br />
discretion of such personnel or officials.  Unauthorized or improper use<br />
of this system may result in civil and criminal penalties and<br />
administrative or disciplinary action, as appropriate. By continuing to<br />
use this system you indicate your awareness of and consent to these terms<br />
and conditions of use. LOG OFF IMMEDIATELY if you do not agree to the<br />
conditions stated in this warning.<br />
****************************************************************************
</p></div>
<p>Restart the ssh daemon and you will no longer be able to connect as root over ssh directly.</p>
<div class="console">
$ sudo /etc/init.d/ssh restart
</div>
<h3> Disabling su </h3>
<p>As per the policy being followed, only users belonging to the &#8216;<em>admin</em>&#8216; group will have any special privileges. For all other users, we shall attempt to lock down the system to the extent feasible. As an early step we shall disable the &#8216;<em>su</em>&#8216; (switch user) command for all but those users belonging to the admin group. <em>Note : since this disables sudo for a brief duration (between the commands), first switch over as a root before executing these commands</em></p>
<div class="console">
$ sudo su -<br />
$ chown root.admin /bin/su /usr/bin/sudo<br />
$ chmod 04750 /bin/su<br />
$ chmod 04550 /usr/bin/sudo
</div>
<p><a name="RootkitDetection"></a></p>
<h2> Install rootkit detection </h2>
<p>Install chkrootkit</p>
<div class="console">
$ sudo apt-get install chkrootkit
</div>
<p>Now create this file <em>/etc/cron.daily/chkrootkit.sh</em> and enter the following contents (replace sever.domain.com with the servername and emailid where you would like the report to be sent to).<br />
Since the mail is rather verbose, and may lead to useful alerts getting ignored, I&#8217;ve removed the lines with the common messages. You may change or not use the grep commands as per your preference.</p>
<div class="console">
#!/bin/bash<br />
/usr/sbin/chkrootkit | \<br />
grep -v &#8220;not found&#8221; | \<br />
grep -v &#8220;nothing found&#8221; | \<br />
grep -v &#8220;not infected&#8221; | \<br />
mail -s &#8220;Daily chkrootkit from server.domain.com&#8221; mailid@destination.com
</div>
<p>Allow execute permissions on the file, and test once by running .. you should get a mail with the report.</p>
<div class="console">
$ sudo chmod 755 /etc/cron.daily/chkrootkit.sh<br />
$ sudo /etc/cron.daily/chkrootkit.sh
</div>
<p><a name="BastilleSetup"></a></p>
<h2> Installing Bastille </h2>
<p>Bastille is a comprehensive package for security configuration.</p>
<p><strong> Bastille Bug? and workaround </strong></p>
<p><em>You may need to perform this workaround if your </em>/etc/debian_version<em> contains 4.0 and the current ubuntu bastille package has not resolved the issue. Ideally one should just need to install bastille from the ubuntu repositories</em></p>
<p>On Ubuntu 9.0.4 (jaunty) as of the day this document was written, I received the following error<br />
~&#038; ERROR:   &#8216;DB5.0&#8242; is not a supported operating system.</p>
<p>I&#8217;ve had a difficulty to install Bastille on Ubuntu 9.0.4. This is due to the fact that Bastille does not support the debian version number in <em>/etc/debian_version</em>. As per Bastille bug reports this got fixed in 3.0.8, but did not work for me in Bastille 3.0.9. Hence the following is a work around to install bastille.</p>
<p>This workaround involves downloading lynx to access internet, downloading the debian package directly, and then installing the debian package. When you reach the web page it will show you a list of mirrors. Download the .deb package from one of the mirrors</p>
<div class="console">
$ sudo apt-get install lynx libcurses-perl<br />
$ lynx http://packages.debian.org/squeeze/all/bastille/download<br />
# Download the package using lynx<br />
$ sudo dpkg &#8211;install bastille_3.0.9-12_all.deb
</div>
<p>Install psad which we shall need later and perl-gtk which we shall need to configure bastille with the following command</p>
<div class="console">
$ sudo apt-get install psad
</div>
<p>You will notice an error message :</p>
<p>To resolve the same execute the following :</p>
<div class="console">
$ echo -e &#8216;kern.info\t|/var/lib/psad/psadfifo&#8217; | sudo tee -a /etc/syslog.conf<br />
$ sudo /etc/init.d/sysklogd restart
</div>
<p>Now run bastille in an interactive mode</p>
<div class="console">
$ sudo bastille -c
</div>
<p>The resultant dialog with bastille is too long and I am just showing the final configuration file which is produced as a result of bastille configuration. <em>I&#8217;ve used the port 22 as a proxy for the SSH port which I assume you&#8217;ve changed to some other value &#8211; use the other value instead of 22</em></p>
<div class="console">
# Q:  Would you like to enforce password aging? [Y]<br />
AccountSecurity.passwdage=&#8221;Y&#8221;<br />
# Q:  Should Bastille disable clear-text r-protocols that use IP-based authentication? [Y]<br />
AccountSecurity.protectrhost=&#8221;Y&#8221;<br />
# Q:  Should we disallow root login on tty&#8217;s 1-6? [N]<br />
AccountSecurity.rootttylogins=&#8221;N&#8221;<br />
# Q:  Would you like to deactivate the Apache web server? [Y]<br />
Apache.apacheoff=&#8221;N&#8221;<br />
# Q:  Would you like to disable CTRL-ALT-DELETE rebooting? [N]<br />
BootSecurity.secureinittab=&#8221;N&#8221;<br />
# Q:  Should we restrict console access to a small group of user accounts? [N]<br />
ConfigureMiscPAM.consolelogin=&#8221;Y&#8221;<br />
# Q:  Which accounts should be able to login at console? [root]<br />
ConfigureMiscPAM.consolelogin_accounts=&#8221;root&#8221;<br />
# Q:  Would you like to put limits on system resource usage? [N]<br />
ConfigureMiscPAM.limitsconf=&#8221;N&#8221;<br />
# Q:  Would you like to set more restrictive permissions on the administration utilities? [N]<br />
FilePermissions.generalperms_1_1=&#8221;Y&#8221;<br />
# Q:  Would you like to disable SUID status for mount/umount?<br />
FilePermissions.suidmount=&#8221;Y&#8221;<br />
# Q:  Would you like to disable SUID status for ping? [Y]<br />
FilePermissions.suidping=&#8221;Y&#8221;<br />
# Q:  Do you need the advanced networking options?<br />
Firewall.ip_advnetwork=&#8221;N&#8221;<br />
# Q:  Interfaces for DHCP queries: [ ]<br />
Firewall.ip_b_dhcpiface=&#8221; &#8221;<br />
# Q:  DNS Servers: [0.0.0.0/0]<br />
Firewall.ip_b_dns=&#8221;0.0.0.0/0&#8243;<br />
# Q:  ICMP allowed types: [destination-unreachable echo-reply time-exceeded]<br />
Firewall.ip_b_icmpallowed=&#8221;destination-unreachable echo-reply time-exceeded&#8221;<br />
# Q:  ICMP services to audit: [ ]<br />
Firewall.ip_b_icmpaudit=&#8221; &#8221;<br />
# Q:  ICMP types to disallow outbound: [destination-unreachable time-exceeded]<br />
Firewall.ip_b_icmpout=&#8221;destination-unreachable time-exceeded&#8221;<br />
# Q:  NTP servers to query: [ ]<br />
Firewall.ip_b_ntpsrv=&#8221; &#8221;<br />
# Q:  Force passive mode? [N]<br />
Firewall.ip_b_passiveftp=&#8221;Y&#8221;<br />
# Q:  Public interfaces: [eth+ ppp+ slip+]<br />
Firewall.ip_b_publiciface=&#8221;eth+&#8221;<br />
# Q:  TCP service names or port numbers to allow on public interfaces: [ ]<br />
Firewall.ip_b_publictcp=&#8221;22 80 443&#8243;<br />
# Q:  UDP service names or port numbers to allow on public interfaces: [ ]<br />
Firewall.ip_b_publicudp=&#8221; &#8221;<br />
# Q:  Reject method: [DENY]<br />
Firewall.ip_b_rejectmethod=&#8221;DENY&#8221;<br />
# Q:  Enable source address verification? [Y]<br />
Firewall.ip_b_srcaddr=&#8221;Y&#8221;<br />
# Q:  TCP services to audit: [telnet ftp imap pop3 finger sunrpc exec login linuxconf ssh]<br />
Firewall.ip_b_tcpaudit=&#8221;telnet ftp imap pop3 finger sunrpc exec login linuxconf ssh&#8221;<br />
# Q:  TCP services to block: [2049 2065:2090 6000:6020 7100]<br />
Firewall.ip_b_tcpblock=&#8221;2049 2065:2090 6000:6020 7100&#8243;<br />
# Q:  UDP services to audit: [31337]<br />
Firewall.ip_b_udpaudit=&#8221;31337&#8243;<br />
# Q:  UDP services to block: [2049 6770]<br />
Firewall.ip_b_udpblock=&#8221;2049 6770&#8243;<br />
# Q:  Should Bastille run the firewall and enable it at boot time? [N]<br />
Firewall.ip_enable_firewall=&#8221;N&#8221;<br />
# Q:  Would you like to run the packet filtering script? [N]<br />
Firewall.ip_intro=&#8221;Y&#8221;<br />
# Q:  Would you like to set up process accounting? [N]<br />
Logging.pacct=&#8221;N&#8221;<br />
# Q:  Would you like to deactivate NFS and Samba? [Y]<br />
MiscellaneousDaemons.remotefs=&#8221;Y&#8221;<br />
# Q:  Alert on all new packets?<br />
PSAD.psad_alert_all=&#8221;Y&#8221;<br />
# Q:  psad check interval: [15]<br />
PSAD.psad_check_interval=&#8221;15&#8243;<br />
# Q:  Would you like to setup psad?<br />
PSAD.psad_config=&#8221;Y&#8221;<br />
# Q:  Danger Levels: [5 50 1000 5000 10000]<br />
PSAD.psad_danger_levels=&#8221;5 50 1000 5000 10000&#8243;<br />
# Q:  Email addresses: [root@localhost]<br />
PSAD.psad_email_alert_addresses=&#8221;mailid@destination.com&#8221;<br />
# Q:  Email alert danger level: [1]<br />
PSAD.psad_email_alert_danger_level=&#8221;1&#8243;<br />
# Q:  Should Bastille enable psad at boot time? [N]<br />
PSAD.psad_enable_at_boot=&#8221;N&#8221;<br />
# Q:  Enable automatic blocking of scanning IPs?<br />
PSAD.psad_enable_auto_ids=&#8221;N&#8221;<br />
# Q:  Enable scan persistence?<br />
PSAD.psad_enable_persistence=&#8221;N&#8221;<br />
# Q:  Port range scan threshold: [1]<br />
PSAD.psad_port_range_scan_threshold=&#8221;1&#8243;<br />
# Q:  Scan timeout: [3600]<br />
PSAD.psad_scan_timeout=&#8221;3600&#8243;<br />
# Q:  Show all scan signatures?<br />
PSAD.psad_show_all_signatures=&#8221;N&#8221;<br />
# Q:  Would you like to disable printing? [N]<br />
Printing.printing=&#8221;Y&#8221;<br />
# Q:  Would you like to disable printing? [N]<br />
Printing.printing_cups=&#8221;N&#8221;<br />
# Q:  Would you like to display &#8220;Authorized Use&#8221; messages at log-in time? [Y]<br />
SecureInetd.banners=&#8221;Y&#8221;<br />
# Q:  Should Bastille ensure inetd&#8217;s FTP service does not run on this system? [y]<br />
SecureInetd.deactivate_ftp=&#8221;Y&#8221;<br />
# Q:  Should Bastille ensure the telnet service does not run on this system? [y]<br />
SecureInetd.deactivate_telnet=&#8221;Y&#8221;<br />
# Q:  Who is responsible for granting authorization to use this machine?<br />
SecureInetd.owner=&#8221;Company Name&#8221;<br />
# Q:  Would you like to set a default-deny on TCP Wrappers and xinetd? [N]<br />
SecureInetd.tcpd_default_deny=&#8221;N&#8221;<br />
# Q:  Do you want to stop sendmail from running in daemon mode? [Y]<br />
Sendmail.sendmaildaemon=&#8221;Y&#8221;<br />
# Q:  Would you like to install TMPDIR/TMP scripts? [N]<br />
TMPDIR.tmpdir=&#8221;N&#8221;
</div>
<p><a name="LampStack"></a></p>
<h2> Installing the Lamp Stack </h2>
<p>Let us use the not so well known <em>tasksel</em> command to download all the packages necessary for a lamp stack. Note that <em>tasksel</em> is simply a convenience tool around <em>apt-get</em> and allows one to install a whole bunch of packages based on a class of necessity &#8211; in this case a <em>LAMP (Linux,Apache,MySQL,PHP)</em> stack.</p>
<div class="console">
$ sudo tasksel install lamp-server
</div>
<p>During the installation you will be required to create the password for the mysql <em>root</em> user. In interest of tight security do make sure to create a really strong password.</p>
<p>This actually sets up the basic LAMP stack and that should get you operational.</p>
<h3> Securing Apache </h3>
<h4> Change the user and group apache runs as </h4>
<p>You may be aware that installation of apache resulted in a new userid and group being created (both called <em>www-data</em>). I just find it a little bit more comforting to change the well known usernames to something that are less predictable. In the steps below I change <em>www-data</em> to <em>apache</em> but you may want to use something a little less predictable than <em>apache</em>.</p>
<div class="console">
$ sudo usermod -l apache www-data<br />
$ sudo groupmod -n apache www-data
</div>
<p>We shall need to change the same in the apache configuration file. Edit the file <em>/etc/apache2/envvars</em> and change the two lines as follows</p>
<div class="console">
export APACHE_RUN_USER=apache<br />
export APACHE_RUN_GROUP=apache
</div>
<h3> Install and configure mod_security </h3>
<p>Earlier when we configured, bastille and through it the iptables firewall, we allowed incoming public traffic on the SSH, HTTP and HTTPS ports. We&#8217;ve already covered the tightening of SSH security. However we still do not have a good way to control HTTP and HTTPS traffic. The solution to that is installing the apache module mod_security. It allows us abilities to inspect and if necessary reject or redirect HTTP/S traffic. The full description of mod_security is beyond the scope of this document, but a good example of how it can be used further to implement application level security as well can be had from the document <a href="http://www.modsecurity.org/documentation/Securing_Web_Services_with_ModSecurity_2.0.pdf">Securing web services with mod_security</a>. Another useful overview page is <a href="http://www.debuntu.org/2006/08/13/86-secure-your-apache2-with-mod-security">Secure your Apache2 with mod-security</a>.</p>
<p>We shall start off with installing mod_security.</p>
<div class="console">
$ sudo apt-get install libapache-mod-security
</div>
<p>You should notice a new file in <em>/etc/apache2/conf.d</em> called <em>security</em>. These are the global mod_security settings.</p>
<p>Change the following variables in the file to make server identification difficult. Note that while these settings do not enhance the security directly, they do make it harder for an intruder to easily identify the specific server and configuration, thus making it harder for him to attempt configuration specific exploits.</p>
<div class="console">
ServerTokens Prod<br />
ServerSignature Off<br />
TraceEnable Off
</div>
<p>Also uncomment the following four lines. Note that this may require you to configure other web applications which are not configured appropriately.</p>
<div class="console">
<Directory /><br />
                AllowOverride None<br />
                Order Deny,Allow<br />
                Deny from all<br />
</Directory>
</div>
<p>While not related to mod_security, to minimise server information leakage, you may consider changing these two variables to the shown values in <em>/etc/php5/apache2/php.ini</em></p>
<div class="console">
expose_php = Off<br />
display_errors = Off
</div>
<p>As mentioned above, there is a whole range of additional controls you can enforce using mod_security. Depending upon your specific requirements feel free to leverage mod_security much more.</p>
<h3> Disable apache modules you do not need </h3>
<p>In general it is better to turn off unrequired modules unless you really need them. The default configuration installs a number of modules which may not be required. The modules that have been enabled are in the <em>/etc/apache2/mods-enabled</em> directory which are all symbolic links to the modules that have been installed in the <em>/etc/apache2/mods-available</em> directory. Note that turning off some modules may affect some web applications you install, in which case you may choose to subsequently turn them on only if necessary. New modules can be enabled with <em>sudo a2enmod module_name</em> command and enabled modules can be disabled by <em>sudo a2dismod module_name command</em>.</p>
<p>Depending upon my requirements, I disabled the following modules</p>
<div class="console">
$ sudo a2dismod autoindex       # used to build directory indexes like the ls command<br />
$ sudo a2dismod cgi             # used to run cgi scripts<br />
$ sudo a2dismod env             # used to set environment variables for CGI &#038; SSI scripts
</div>
<h4> Chrooting apache </h4>
<p>This is an advanced topic that I shall skip. Note that if you do setup chrooting, there&#8217;s a lot of additional considerations which will need to be observed, considerations especially around shared libraries and configuration files which will make the overall process of configuration extremely difficult.</p>
<p><a name="SnortSetup"></a></p>
<h2>Setting up snort and acidbase</h2>
<p><em>Author&#8217;s Note: Careful &#8211; Very likely, there were a few things that I might have missed or incorrectly noted especially in the context of acidbase and following these instructions may not get acidbase running properly. You may have to do some steps outside these notes to get it all working properly. Unfortunately I am unable to rerun the process on a fresh server so am unable to immediately note the possible lacunae in the notes</em></p>
<p>Now that you have a mysql server going, create a new database for snort. In the following section I use <em>snortdb</em> as the database, <em>snort</em> as the user and <em>snortpwd</em> as the password for the database. However I do encourage you to replace the same with some non easily guessable names and passwords.</p>
<p>Here&#8217;s the commands to create a new snort database and user. In the following example &#8216;<em>$</em>&#8216; is the unix prompt while &#8216;<em>></em>&#8216; is the mysql prompt.</p>
<div class="console">
$ mysql -u root -p      # You will be prompted for the password for the mysql root account. Enter it<br />
> create database snortdb;<br />
> grant select, insert, update, delete, create, drop, index, alter, create temporary tables, lock tables on snortdb.* to &#8216;snort&#8217;@'localhost&#8217; identified by &#8216;snortpwd&#8217;;<br />
> flush privileges;<br />
> quit;
</div>
<p>Now we shall install snort.</p>
<div class="console">
$ sudo apt-get install snort-mysql
</div>
<p>The installation process will require you to enter the network that you wish to protect. Since in this case we are only protecting a single machine, enter the IP_Address/32 eg. 12.34.56.78/32</p>
<p>The process will prompt you whether you wish to configure the database. Select &#8220;Yes&#8221; .. the script will proceed but terminate abnormally with the error &#8220;subprocess post-installation script returned error exit status 6&#8243;</p>
<p>Now execute the following commands to setup the tables in the database. At the end you shall open the snort configuration file to enter the database configuration parameters</p>
<div class="console">
$ cd /usr/share/doc/snort-mysql<br />
# Enter the database password next when prompted for one<br />
$ sudo zcat create_mysql.gz | mysql -u snort -p snortdb<br />
$ sudo vi /etc/snort/snort.conf
</div>
<p>Uncomment the line that starts with <em>output database: log, mysql</em> and add the configuration information at the end as shown</p>
<div class="console">
output database: log, mysql, user=snort password=snortpwd dbname=snortdb host=localhost
</div>
<p>Now remove the file as shown below to indicate that the database configuration has been done and start snort. The subsequent command confirms that snort daemon is indeed up and running</p>
<div class="console">
$ sudo rm -rf /etc/snort/db-pending-config<br />
$ sudo /etc/init.d/snort start<br />
$ sudo /etc/init.d/snort status
</div>
<p>Now, lets install acid which is a web based application to be able to view snort alerts</p>
<div class="console">
$ sudo apt-get install acidbase
</div>
<p>Select No when it prompts you for configuring the database. By default it uses the database and userid &#8216;<em>snort</em>&#8216; and I prefer to keep these different from a predictable default, in which case acidbase database initialisation will fail.</p>
<p>Edit the file <em>/etc/dbconfig-common/acidbase.conf</em>.</p>
<p>Set the following values</p>
<div class="console">
dbc_dbuser=&#8217;snort&#8217;<br />
dbc_dbpass=&#8217;snortpwd&#8217;<br />
dbc_dbname=&#8217;snortdb&#8217;
</div>
<p>The default configuration allows acid data to be accessed only from the machine where it is involved. Since this shall be a VPS which we shall be accessing remotely, it is time to relax the constraint. If you have a good idea of the network IPs that you will be accessing the acid web application from, update the same in the <em>allow from</em> directive in <em>/etc/acidbase/apache.conf</em>, else relax it fully to <em>allow from all</em>.</p>
<p>Also protect the &#8216;<em>/acidbase</em>&#8216; url by http basic authentication. The resultant section in the file <em>/etc/acidbase/apache.conf</em> looks like :</p>
<div class="console">
<DirectoryMatch /usr/share/acidbase/><br />
  Options +FollowSymLinks<br />
  AuthType Basic<br />
  AuthName &#8220;Go Away World!<br />
  AuthUserFile /etc/acidbase/mypassword<br />
  Require valid-user<br />
  AllowOverride None<br />
  order deny,allow<br />
  deny from all<br />
  allow from all<br />
  <IfModule mod_php4.c><br />
        php_flag magic_quotes_gpc Off<br />
        php_flag track_vars On<br />
        php_value include_path .:/usr/share/php<br />
  </IfModule><br />
</DirectoryMatch>
</div>
<p>You will need to create a user id / password pair for the app or point AuthUserFile above to another file where you already have the ones set up for your server.</p>
<p>To do so you shall need to run the following command :</p>
<div class="console">
$ htpasswd -c /etc/acidbase/mypassword my_user_id
</div>
<p>If you need additional user ids to be installed use the command as shown above again with different user ids &#8211; but make sure not to use the <em>-c</em> switch since thats only used the first time to create the password file.</p>
<p>Now start the web application by restarting apache</p>
<div class="console">
$ sudo /etc/init.d/apache2 restart
</div>
<p>Goto the web page <em>http:</em>vps_fully_qualified_domain_name/acidbase/base_db_setup.php<em>, click on &#8216;</em>Create Base AG//&#8217; and you are on your way.</p>
<p><a name="FileIntegrity"></a></p>
<h2>File integrity checking using AIDE</h2>
<p>Install AIDE</p>
<div class="console">
$ sudo apt-get install aide
</div>
<p>Update the aide configuration file <em>etc/default/aide</em> to update your email id where you would prefer the integrity check reports sent (Look for the variable MAILTO)<br />
Now initialise the aide configuration</p>
<div class="console">
$ sudo aideinit<br />
$ cd /var/lib/aide<br />
$ mv aide.db.new aide.db
</div>
<p>Now run the process (which will be running once daily)</p>
<div class="console">
$ /etc/cron.daily/aide
</div>
<p>This process takes a long time (about 5 mins for me) and will at the end email you a report if any files changed compared to the ones in the default database.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=rDQBoHSlFSg:Lqx7nszeA4I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=rDQBoHSlFSg:Lqx7nszeA4I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=rDQBoHSlFSg:Lqx7nszeA4I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=rDQBoHSlFSg:Lqx7nszeA4I:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=rDQBoHSlFSg:Lqx7nszeA4I:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=rDQBoHSlFSg:Lqx7nszeA4I:cGdyc7Q-1BI"><img src="http://feeds.feedburner.com/~ff/var/log/mind?d=cGdyc7Q-1BI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/var/log/mind/~4/rDQBoHSlFSg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/10/configuring-a-secure-ubuntu-linux-virtual-private-server/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/10/configuring-a-secure-ubuntu-linux-virtual-private-server/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=configuring-a-secure-ubuntu-linux-virtual-private-server</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 4.064 seconds -->

