<?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>Mon, 01 Mar 2010 17:35:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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>Functional Programming with Python – Part 2 – Useful python constructs</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/CeiRmXsoDJM/</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 [...]]]></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: black;">&#91;</span>1,2,3,4,5<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: black;">&#123;</span><span style="color: #ff4500;">1</span>:<span style="color: #483d8b;">&quot;One&quot;</span>, <span style="color: #ff4500;">2</span>: <span style="color: #483d8b;">&quot;Two&quot;</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,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, 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: black;">&#91;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">2</span>,<span style="color: #ff4500;">3</span>,<span style="color: #ff4500;">4</span>,<span style="color: #ff4500;">5</span>,<span style="color: #ff4500;">6</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>,begin,end<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>._next = begin - 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">end</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 += 1<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>,begin,end<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">begin</span> = begin<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">end</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: #008000;">self</span>.<span style="color: black;">end</span><span style="color: black;">&#41;</span><br />
<br />
oneToFive = Range<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</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> <span style="color: #66cc66;">%</span> number<br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Is 2 in oneToFive'</span>, 2 <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>, 9 <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, end<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; current = 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 += 1<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>1,5<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> <span style="color: #66cc66;">%</span> number<br />
<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Is 2 in oneToFive'</span>, 2 <span style="color: #ff7700;font-weight:bold;">in</span> my_range<span style="color: black;">&#40;</span>1,5<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>, 9 <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: #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: 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>10<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> num <span style="color: #66cc66;">%</span> 2 == 0<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: #ff4500;">2</span>, <span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">6</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 <span style="color: #66cc66;">*</span> 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: #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 <span style="color: #66cc66;">*</span> num,<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: #66cc66;">%</span> 2 == 0, <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,num : reduced + <span style="color: black;">&#40;</span>num <span style="color: #66cc66;">*</span> num<span style="color: black;">&#41;</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: #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: 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>5<span style="color: black;">&#41;</span> :<br />
&nbsp; &nbsp; seq = seq + <span style="color: black;">&#91;</span>num <span style="color: #66cc66;">*</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;">#filter</span><br />
seq = <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>5<span style="color: black;">&#41;</span> :<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> num <span style="color: #66cc66;">%</span> 2 == 0 :<br />
&nbsp; &nbsp; &nbsp; &nbsp; seq = 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 = 0<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>5<span style="color: black;">&#41;</span> : <br />
&nbsp; &nbsp; total = total + <span style="color: black;">&#40;</span>num <span style="color: #66cc66;">*</span> 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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2010/02/functional-programming-with-python-part-1/' rel='bookmark' title='Permanent Link: Functional Programming with Python &#8211; Part 1'>Functional Programming with Python &#8211; Part 1</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/04/a-brush-with-functional-programming-and-scala/' rel='bookmark' title='Permanent Link: A brush with Functional Programming and Scala'>A brush with Functional Programming and Scala</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/03/constructor-method-overloading-in-python/' rel='bookmark' title='Permanent Link: Constructor / Method overloading in Python using Function Switching'>Constructor / Method overloading in Python using Function Switching</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=CeiRmXsoDJM: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=CeiRmXsoDJM:n1wtSNs51PA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=CeiRmXsoDJM:n1wtSNs51PA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=CeiRmXsoDJM:n1wtSNs51PA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=CeiRmXsoDJM:n1wtSNs51PA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=CeiRmXsoDJM: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/CeiRmXsoDJM" 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/</feedburner:origLink></item>
		<item>
		<title>Functional Programming with Python – Part 1</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/cV1_rFjv0Ck/</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 />
	<!-- 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 quote from [...]]]></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 = namedtuple<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Context'</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>,0.0,<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,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,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,y<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> x <span style="color: #66cc66;">*</span> y<br />
<span style="color: #ff7700;font-weight:bold;">def</span> div<span style="color: black;">&#40;</span>x,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> -1 <span style="color: #66cc66;">*</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,y<span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> x <span style="color: #66cc66;">**</span> 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 = add<br />
add = sub<br />
<span style="color: #ff7700;font-weight:bold;">assert</span> otheradd<span style="color: black;">&#40;</span>7,3<span style="color: black;">&#41;</span> == 10<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: #ff4500;">3</span><span style="color: black;">&#41;</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 = partial<span style="color: black;">&#40;</span><span style="color: #008000;">pow</span>,y=<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: black;">&#123;</span><span style="color: #483d8b;">'!'</span> : reverse_sign, <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,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 = 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>, op = <span style="color: #008000;">None</span><span style="color: black;">&#41;</span><br />
<br />
binary_functions = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'+'</span> : add, <span style="color: #483d8b;">'-'</span> : sub, <span style="color: #483d8b;">'*'</span> : mult, <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,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 = 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,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 = 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 = ctx.<span style="color: black;">op</span><span style="color: black;">&#40;</span>ctx.<span style="color: black;">current</span>,x<span style="color: black;">&#41;</span>, op = <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 = 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>,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 = newstack, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current = 0.0, op = <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 = ctx.<span style="color: black;">stack</span><br />
&nbsp; &nbsp; current = ctx.<span style="color: black;">current</span><br />
&nbsp; &nbsp; oldcurrent, oldop = 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 = Context<span style="color: black;">&#40;</span>stack,oldcurrent,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,current<span style="color: black;">&#41;</span><br />
<br />
tokens = <span style="color: black;">&#123;</span> <span style="color: #483d8b;">'('</span>: start_brace, <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,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: 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,<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,<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,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: black;">&#40;</span><span style="color: #dc143c;">types</span>.<span style="color: black;">FloatType</span>,<span style="color: #dc143c;">types</span>.<span style="color: black;">IntType</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,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: 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,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,key : process_key<span style="color: black;">&#40;</span>ctx,key<span style="color: black;">&#41;</span>, keys, 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 = 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 = process_key<span style="color: black;">&#40;</span>ctx,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: #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: #483d8b;">'+'</span>, 3<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> == 5<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: #483d8b;">'!'</span>, <span style="color: #483d8b;">'+'</span>, 5<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> == 3<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: #483d8b;">'@'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> == 4<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: #483d8b;">'+'</span>,<span style="color: #ff4500;">3</span>,<span style="color: #483d8b;">'*'</span>,5<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">current</span> == 25<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: #483d8b;">'+'</span>,<span style="color: #483d8b;">'('</span>,<span style="color: #ff4500;">3</span>,<span style="color: #483d8b;">'*'</span>,<span style="color: #ff4500;">5</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: #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 = 1<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>, count<br />
&nbsp; &nbsp; &nbsp; &nbsp; count += 1<br />
<br />
keys = <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>10<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>1:<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: #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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2010/03/functional-programming-with-python-%e2%80%93-part-2-useful-python-constructs/' rel='bookmark' title='Permanent Link: Functional Programming with Python – Part 2 &#8211; Useful python constructs'>Functional Programming with Python – Part 2 &#8211; Useful python constructs</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/04/a-brush-with-functional-programming-and-scala/' rel='bookmark' title='Permanent Link: A brush with Functional Programming and Scala'>A brush with Functional Programming and Scala</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/03/constructor-method-overloading-in-python/' rel='bookmark' title='Permanent Link: Constructor / Method overloading in Python using Function Switching'>Constructor / Method overloading in Python using Function Switching</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=cV1_rFjv0Ck: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=cV1_rFjv0Ck:W9JvDniwzcE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=cV1_rFjv0Ck:W9JvDniwzcE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=cV1_rFjv0Ck:W9JvDniwzcE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=cV1_rFjv0Ck:W9JvDniwzcE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=cV1_rFjv0Ck: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/cV1_rFjv0Ck" 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/</feedburner:origLink></item>
		<item>
		<title>Google Buzz Test Drive Report</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/7Xlc7s7S9lI/</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 enter comments against [...]]]></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=7Xlc7s7S9lI: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=7Xlc7s7S9lI:dw4Kl6WoPxw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=7Xlc7s7S9lI:dw4Kl6WoPxw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7Xlc7s7S9lI:dw4Kl6WoPxw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=7Xlc7s7S9lI:dw4Kl6WoPxw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7Xlc7s7S9lI: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/7Xlc7s7S9lI" 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/</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/KZmxdrUtOoM/</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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/06/improve-your-web-based-software-development-and-maintenance-roi-with-dynamic-programming-languages/' rel='bookmark' title='Permanent Link: Improve your web based software development and maintenance ROI with dynamic programming languages'>Improve your web based software development and maintenance ROI with dynamic programming languages</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/03/agile-andor-process-maturity-how-do-i-perceive-these-terms-and-why-these-should-not-be-confused/' rel='bookmark' title='Permanent Link: Agility and/or Process Maturity : How do I perceive these terms and why these should not be confused'>Agility and/or Process Maturity : How do I perceive these terms and why these should not be confused</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=KZmxdrUtOoM:-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=KZmxdrUtOoM:-8WklZHzwK4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=KZmxdrUtOoM:-8WklZHzwK4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=KZmxdrUtOoM:-8WklZHzwK4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=KZmxdrUtOoM:-8WklZHzwK4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=KZmxdrUtOoM:-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/KZmxdrUtOoM" 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/</feedburner:origLink></item>
		<item>
		<title>Concise python code</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/fWBTNeDzXt0/</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: #483d8b;">&quot;bar&quot;</span>,<span style="color: #483d8b;">&quot;baz&quot;</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,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: black;">&#40;</span><span style="color: #483d8b;">&quot;foo&quot;</span>,<span style="color: #483d8b;">&quot;bar&quot;</span>,<span style="color: #483d8b;">&quot;baz&quot;</span>,<span style="color: #483d8b;">&quot;foo&quot;</span><span style="color: black;">&#41;</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>1,1000<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">if</span> i<span style="color: #66cc66;">%</span>3 == 0 <span style="color: #ff7700;font-weight:bold;">or</span> i<span style="color: #66cc66;">%</span>5 == <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,y = 1,1<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span> :<br />
&nbsp; &nbsp; &nbsp; &nbsp; x,y = y,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> 4000000,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: #66cc66;">%</span>2 == <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 <span style="color: #66cc66;">*</span> 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>100,1000<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>100,1000<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<span style="color: #66cc66;">*</span>y<span style="color: black;">&#41;</span> == <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>x<span style="color: #66cc66;">*</span>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: black;">&#91;</span><span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>name=<span style="color: #483d8b;">&quot;Tyler Bennett&quot;</span>, <span style="color: #008000;">id</span>=<span style="color: #483d8b;">&quot;E10297&quot;</span>, salary=<span style="color: #ff4500;">32000</span>, department=<span style="color: #483d8b;">&quot;D101&quot;</span><span style="color: black;">&#41;</span>, ...<span style="color: black;">&#93;</span><br />
<br />
department = 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, 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, key=department<span style="color: black;">&#41;</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>, 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, key=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: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Employee Name'</span>, <span style="color: #483d8b;">'Employee ID'</span>, <span style="color: #483d8b;">'Salary'</span>, <span style="color: #483d8b;">'Department'</span><span style="color: black;">&#41;</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,y : x + y,<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> <span style="color: #66cc66;">%</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,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: #66cc66;">*</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#91;</span>0<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">%</span> y<span style="color: black;">&#41;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>recs, key=<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: #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, 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>1:<span style="color: black;">&#93;</span>,key=<span style="color: #dc143c;">operator</span>.<span style="color: black;">itemgetter</span><span style="color: black;">&#40;</span>3<span style="color: black;">&#41;</span><span style="color: black;">&#41;</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: #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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2010/03/functional-programming-with-python-%e2%80%93-part-2-useful-python-constructs/' rel='bookmark' title='Permanent Link: Functional Programming with Python – Part 2 &#8211; Useful python constructs'>Functional Programming with Python – Part 2 &#8211; Useful python constructs</a></li>
<li><a href='http://blog.dhananjaynene.com/2010/02/functional-programming-with-python-part-1/' rel='bookmark' title='Permanent Link: Functional Programming with Python &#8211; Part 1'>Functional Programming with Python &#8211; Part 1</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/03/constructor-method-overloading-in-python/' rel='bookmark' title='Permanent Link: Constructor / Method overloading in Python using Function Switching'>Constructor / Method overloading in Python using Function Switching</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=fWBTNeDzXt0: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=fWBTNeDzXt0:JE76a6hz53Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=fWBTNeDzXt0:JE76a6hz53Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=fWBTNeDzXt0:JE76a6hz53Y:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=fWBTNeDzXt0:JE76a6hz53Y:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=fWBTNeDzXt0: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/fWBTNeDzXt0" 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/</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/NmY3cDOnS-0/</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>&#8217;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=NmY3cDOnS-0: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=NmY3cDOnS-0:eqsb9s8aUa8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=NmY3cDOnS-0:eqsb9s8aUa8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=NmY3cDOnS-0:eqsb9s8aUa8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=NmY3cDOnS-0:eqsb9s8aUa8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=NmY3cDOnS-0: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/NmY3cDOnS-0" 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/</feedburner:origLink></item>
		<item>
		<title>Rinse and Repeat with TDD</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/79cuknLPIGc/</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=79cuknLPIGc: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=79cuknLPIGc:YTbGwYkJ3RQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=79cuknLPIGc:YTbGwYkJ3RQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=79cuknLPIGc:YTbGwYkJ3RQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=79cuknLPIGc:YTbGwYkJ3RQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=79cuknLPIGc: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/79cuknLPIGc" 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/</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/ZrfVo4xE1Q4/</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 builds [...]]]></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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/' rel='bookmark' title='Permanent Link: REST is the DBMS of the Internet'>REST is the DBMS of the Internet</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/why-rest/' rel='bookmark' title='Permanent Link: Why REST ?'>Why REST ?</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/' rel='bookmark' title='Permanent Link: Design Characteristics of REST / Resource Oriented Server Frameworks and Clients'>Design Characteristics of REST / Resource Oriented Server Frameworks and Clients</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ZrfVo4xE1Q4: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=ZrfVo4xE1Q4:740DIcOFQ_o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=ZrfVo4xE1Q4:740DIcOFQ_o:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ZrfVo4xE1Q4:740DIcOFQ_o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=ZrfVo4xE1Q4:740DIcOFQ_o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ZrfVo4xE1Q4: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/ZrfVo4xE1Q4" 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/</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/hAwfiGcjzbw/</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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/10/service-oriented-rest-architecture-is-an-oxymoron/' rel='bookmark' title='Permanent Link: Service oriented REST architecture is an oxymoron'>Service oriented REST architecture is an oxymoron</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/' rel='bookmark' title='Permanent Link: Design Characteristics of REST / Resource Oriented Server Frameworks and Clients'>Design Characteristics of REST / Resource Oriented Server Frameworks and Clients</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=hAwfiGcjzbw: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=hAwfiGcjzbw:YCxpklrekkI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=hAwfiGcjzbw:YCxpklrekkI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=hAwfiGcjzbw:YCxpklrekkI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=hAwfiGcjzbw:YCxpklrekkI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=hAwfiGcjzbw: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/hAwfiGcjzbw" 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/</feedburner:origLink></item>
		<item>
		<title>Stop calling me NoSQL</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/gDeGmt9gBeY/</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 inappropriate [...]]]></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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/10/nosql-a-fluid-architecture-in-transition/' rel='bookmark' title='Permanent Link: NoSQL &#8211; A fluid architecture in transition'>NoSQL &#8211; A fluid architecture in transition</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/11/five-important-trends-on-the-enterprise-architects-radar/' rel='bookmark' title='Permanent Link: Five important trends on the enterprise architect&#8217;s radar'>Five important trends on the enterprise architect&#8217;s radar</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=gDeGmt9gBeY: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=gDeGmt9gBeY:sFDOHza25Ew:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=gDeGmt9gBeY:sFDOHza25Ew:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=gDeGmt9gBeY:sFDOHza25Ew:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=gDeGmt9gBeY:sFDOHza25Ew:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=gDeGmt9gBeY: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/gDeGmt9gBeY" 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/</feedburner:origLink></item>
		<item>
		<title>NoSQL – A fluid architecture in transition</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/NPxdbON88Js/</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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/10/stop-calling-me-nosql/' rel='bookmark' title='Permanent Link: Stop calling me NoSQL'>Stop calling me NoSQL</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/11/five-important-trends-on-the-enterprise-architects-radar/' rel='bookmark' title='Permanent Link: Five important trends on the enterprise architect&#8217;s radar'>Five important trends on the enterprise architect&#8217;s radar</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=NPxdbON88Js: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=NPxdbON88Js:LRIrmzvjZ3k:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=NPxdbON88Js:LRIrmzvjZ3k:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=NPxdbON88Js:LRIrmzvjZ3k:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=NPxdbON88Js:LRIrmzvjZ3k:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=NPxdbON88Js: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/NPxdbON88Js" 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/</feedburner:origLink></item>
		<item>
		<title>Configuring a secure Ubuntu Linux Virtual Private Server</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/ej6qH7i64xA/</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 &#8217;snort&#8217;@'localhost&#8217; identified by &#8217;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>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/06/opera-unite-a-model-for-server-disintermediation-on-the-internet/' rel='bookmark' title='Permanent Link: Opera Unite : A model for server disintermediation on the internet'>Opera Unite : A model for server disintermediation on the internet</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ej6qH7i64xA: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=ej6qH7i64xA:Lqx7nszeA4I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=ej6qH7i64xA:Lqx7nszeA4I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ej6qH7i64xA:Lqx7nszeA4I:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=ej6qH7i64xA:Lqx7nszeA4I:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ej6qH7i64xA: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/ej6qH7i64xA" 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/</feedburner:origLink></item>
		<item>
		<title>Service oriented REST architecture is an oxymoron</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/R2iR83i_aDY/</link>
		<comments>http://blog.dhananjaynene.com/2009/10/service-oriented-rest-architecture-is-an-oxymoron/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 21:34:41 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[rest-musings]]></category>
		<category><![CDATA[soa]]></category>
		<category><![CDATA[web services]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=835</guid>
		<description><![CDATA[It is infrequent for me to react with a level of consternation rather than agreement or disagreement that I felt upon reading [SOA] Boris on Service, Web and REST by Jean-Jacques Dubray. Not because I disagreed strongly with the arguments presented. It is that, I disagree substantially with the assumptions on which these arguments are [...]]]></description>
			<content:encoded><![CDATA[<p>It is infrequent for me to react with a level of consternation rather than agreement or disagreement that I felt upon reading <a href="http://www.ebpml.org/blog/200.htm">[SOA] Boris on Service, Web and REST</a> by Jean-Jacques Dubray. Not because I disagreed strongly with the arguments presented. It is that, I disagree substantially with the assumptions on which these arguments are made. And yet, as I recollect my own thoughts a year ago &#8211; a few months post my journey into REST, I realised that there was a time that I did actually believe some of these assumptions. I also realised that it is likely that many others who are dealing with a transition from SOA to REST are also likely to be perhaps sharing similar assumptions. Without much ado let me quickly get to the central assertion of this blog post.</p>
<p><strong><em>Service orientation is neither essential for, nor is it the intention of REST.<br/> Not only is REST not service oriented, service orientation is irrelevant for REST</em></strong></p>
<p><br/>There. But why was it so important to state that ? Allow me to quote from the blog post I referred to.</p>
<blockquote><p>I say not surprisingly because RESTafarians have no clear position on &#8220;service&#8221;, they just say REST is the right way to build a Service Oriented Architecture. Yet, REST has no concept of &#8220;service&#8221; anywhere, just resources and their shiny uniform interface, links and bookmarks. Indeed there are no services in REST. Just read the thesis.</p></blockquote>
<p>and it further goes on to state</p>
<blockquote><p>But I digress, let&#8217;s go back to &#8220;services&#8221;. Even Bill, in this REST-* proposal is talking about creating a RESTful interface to non RESTful services. That certainly begs the question, how can a service be non RESTful since REST is all about SOA and replaces in its entirety WS-*.</p></blockquote>
<p>The essential issue here is the flawed assumption that REST attempts to be service oriented or it is all about SOA. Its not. And why so ? Since it is resource oriented. And whats the difference ? Read on, because that&#8217;s what this post attempts to address.</p>
<p><strong>Service</strong></p>
<p>Wikipedia describes a <a href="http://en.wikipedia.org/wiki/Service_%28systems_architecture%29">service</a> as follows :</p>
<blockquote><p> the term service refers to a set of related software functionality, together with the policies that should control their usage.</p>
<p>OASIS (organization) defines service as &#8220;a mechanism to enable access to one or more capabilities, where the access is provided using a prescribed interface and is exercised consistent with constraints and policies as specified by the service description.&#8221;</p></blockquote>
<p>Now lets attempt to understand a service in a little more dumbed down fashion. Lets hark back to the good old construct of flow charts and process charts. In these charts one basically divided an overall set of functionality into discrete set of functionalities and chained them together through some sequences and decision points. As an example if we were to consider a simplified retail outlet system, it would consist of steps that would support (a) ordering items, (b) receiving and reviewing items, (c) selling items. In a SOA world, these could be mapped into a Ordering Service, Receipt Service and Sales Service (you could of course come up with better names and further decomposition). But each service is essentially one of the decomposed tasks of a larger workflow. If the interface to such service could be standardised and documented it would help it to be reusable across multiple contexts. And to the extent such services are reusable across multiple workflows, the advantage of Service Orientation become obvious. And finally if such a service interfaces are exposed over the web &#8211; it is a web service. At the end of the day, each service is a reusable, composable task (or tasklet) performer.</p>
<p><strong>Resources</strong></p>
<p>But REST does not attempt to be service oriented. Thats because it does not view the process as a sequence of tasks to be performed. It views it as a sequence of resources under modification. To put it differently, it views the process as a set of actors who exchange resources (or documents for better visualisation) and carry out activities based upon receipt of such resources. Though not as equally apt as a process chart, the analogy here would be a data flow diagram. And what might such resources be ? Well in the above scenario, there&#8217;s a Purchase Order, a Goods Receipt and an Invoice. Those are the essential abstractions that REST focuses on. These are Resources. Just like Services where there&#8217;s no one valid set of abstraction of services, one could work out a different set of resources rather than those I listed. But the bottom line is that the essential abstractions are resources *not* services.</p>
<p><strong>How are they different ?</strong></p>
<p>You could build a system either way &#8211; as services or resources. In terms of being able to successfully build, deploy and maintain a piece of software, both REST and SOA are likely to be equally successful at building the software. But the essential vocabulary through which they decompose their various parts (and therefore describe their interface elements) will be different. And how is that different ?</p>
<p>Let us imagine the ordering service we talked about above. One way to build a SOA ordering service is to establish a interaction procedure which combines an overall protocol and a series of steps (Service API). To reduce potential errors, there is a document upfront which describes in adequate detail how such an interaction should be conducted, what are the data elements to be exchanged at each stage, and what are the necessary sequencing requirements between various steps for such interactions to be concluded successfully (WSDL). The focus here is the tasks being done and the protocol for the task instructions. In case of REST the essential construct will be exchange of one Purchase Order. The purchase order would have sufficient in band instructions about the fact that it is a purchase order and the attributes it has (in-band metadata), and formal documentation if any would be restricted to the structure of the purchase order and its data than than to the sequencing, flow or any protocol level activities. (Thats why sometimes REST looks deceptively simple to be treated as just another CRUD). </p>
<p>More often than not when called upon to describe a service, the description will describe what the service does, and the service interface will mirror the steps required to perform the activities. Resources on the other hand will simply describe themselves and anyone who looks at a resource description will be none the wiser about what processing exactly happens behind the scene.</p>
<p>Thats why I believe even if both REST and SOA can be used to build software effectively, the essential focus on resources as the central abstraction makes REST much easier to use for the clients. But thats just my opinion &#8211; you may form your own.</p>
<p><strong>You cheated! REST meets the service orientation definitions you listed above</strong></p>
<p>Yeah, kind of (in theory). There is one way where REST over HTTP is service oriented. Imagine a document service which could store, update, fetch or delete documents. Now replace document with resource in the earlier statement. Thats your typical HTTP service that REST works off of to implement a resource management service &#8211; but thats just a single service which is standardised for REST over HTTP.  And all REST implementations will be service oriented to that extent. However the sheer simplicity and ubiquity of this service makes the associated service orientation of REST rather uninteresting and thus largely ignorable.</p>
<p>So next time one wants to debate the merits for REST and/or SOA &#8211; feel free to add to the tons of stuff thats already written. But don&#8217;t measure REST based on service orientation. Service orientation is largely irrelevant for REST. And that per se does not make one better than other &#8211; it just makes them different.</p>
<p><em>Note:</em> There were many other points in the blog post I referred to that I would want to offer different opinions on. But in this case, I believed it was important to keep this post focused on an essential thought that I really wanted to emphasize.</p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/10/service-oriented-architecture-is-primarily-about-business-and-not-technology.-bollocks/' rel='bookmark' title='Permanent Link: Service Oriented Architecture is primarily about business and not technology. Bollocks!'>Service Oriented Architecture is primarily about business and not technology. Bollocks!</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/' rel='bookmark' title='Permanent Link: Design Characteristics of REST / Resource Oriented Server Frameworks and Clients'>Design Characteristics of REST / Resource Oriented Server Frameworks and Clients</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/rest-soa-woa-or-roa/' rel='bookmark' title='Permanent Link: ReST : SOA, WOA or ROA ?'>ReST : SOA, WOA or ROA ?</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=R2iR83i_aDY:sF2Rn2Dobc0: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=R2iR83i_aDY:sF2Rn2Dobc0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=R2iR83i_aDY:sF2Rn2Dobc0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=R2iR83i_aDY:sF2Rn2Dobc0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=R2iR83i_aDY:sF2Rn2Dobc0:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=R2iR83i_aDY:sF2Rn2Dobc0: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/R2iR83i_aDY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/10/service-oriented-rest-architecture-is-an-oxymoron/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/10/service-oriented-rest-architecture-is-an-oxymoron/</feedburner:origLink></item>
		<item>
		<title>The best amount of polyglotism is that you can manage successfully</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/nzPGzuOKpdU/</link>
		<comments>http://blog.dhananjaynene.com/2009/09/the-best-amount-of-polyglotism-is-that-you-can-manage-successfully/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 13:05:20 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[management]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[polyglot]]></category>
		<category><![CDATA[polyglotism]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=829</guid>
		<description><![CDATA[Polyglotism was one topic I got into some discussions on twitter earlier this week. So this is to just pen down some of my thoughts on the same. Polyglotism is increasingly being talked about, ever more so since Java started moving from the realm of being a language into a runtime environment to host a [...]]]></description>
			<content:encoded><![CDATA[<p>Polyglotism was one topic I got into some discussions on twitter earlier this week. So this is to just pen down some of my thoughts on the same. Polyglotism is increasingly being talked about, ever more so since Java started moving from the realm of being a language into a runtime environment to host a number of languages. Yet polyglotism is not new. Most programmers have been mixing their favourite languages with SQL for ages. The advent of the web introduced HTML and javascript as additional languages that web programmers needed to know to be able to successfully write web programs. At the same time other tools started appearing which started to reduce your requirement to know these languages. <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">Object Relationship Mappers</a> could help you get out of writing SQLs (at least so they claimed <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) in many cases. And one of the features of <a href="http://code.google.com/webtoolkit/overview.html">GWT</a> is to ensure that you work primarily on only one language.</p>
<p>But the goal of this post is to neither encourage nor discourage the use of polyglotism. It is to suggest that at the end of the day even if polyglotism really stimulates the technogeek sensors in us, it needs to be evaluated not in technology terms, but in business and economic terms. A point that is also partially supported by <a href="http://www.codecommit.com/blog/java/the-plague-of-polyglotism">The plague of polyglotism</a>. Unless we use tools like GWT and hibernate to keep us monoglots, (which is likely to be a very small proportion), polyglotism is the default state that we shall operate in. So its not worthwhile to fight that trend per se. The important aspect is to ensure that we understand the costs of supporting each new language in the mix. And the reason to do so is to evaulate whether the benefits of adding the language outweigh the costs in the medium to long term. So here are some of the costs (in no specific order)</p>
<ul>
<li><strong>Syntax and libraries</strong> : This is probably one of the lowest costs even though it is the most apparent. For every language we add to the mix, generally for a long running project, at least three developers (if you have reasonable risk management objectives) need to learn the new language syntax and the libraries they work with. Along with this is the cost of books, training courses and materials etc. (yes for many enterprises, many developers but those purely self motivated will need to be formally provided all of these).</li>
<li><strong>Idioms and Philosophies</strong> : Knowing the language is not adequate. You need to understand its philosophy, its design intent and its typical idioms. Being able to use a language to write code is not the same as being able to use it idiomatically. And while that may not constrain you in over small code bases in the short term, over a period of time for reasons such as performance, consistency and ability to understand other libraries that you may reuse, you will be forced to deal with these aspects of the language as well. The book<a href="http://en.wikipedia.org/wiki/Dreaming_in_code"> Dreaming in Code</a> talks about how Java programmers who started writing python could not write idiomatic python code, and thus a fair degree of code had to be redesigned or rewritten. And that is by no means the only such instance. I suspect similar trends are likely to be found if java programmers move to writing ruby or scala code. And its a trend you might have likely observed when people comfortable with writing relatively simpler languages such as Visual Basic or PL/SQL or even more complex languages like C++ moved to writing Java. Knowing the language is not the same as knowing it idiomatically &#8211; and that takes time. Which means &#8211; do not take on high risk activities when you absorb a new language, it will take a few iterations for your team to absorb the new language &#8211; far far more time than it will take to read a book or attend a training course.</li>
<li><strong>Skills to manage multiple idioms in one head </strong> : Unless you are going to have different programmers for different languages, the programmers working on multiple languages at a time will not only have to deal with the multiple idioms, but will need to concurrently apply them. In my experience, this is not a trait we are born with, and it takes some time and experience with it. It will take some time for them to learn that the best practices are not identical across various languages. It will take even more time to figure out why they are different. So there is a good likelihood, you will not be in a situation to have all your developers work on all the languages simultaneously &#8211; especially some of the Junior ones. </li>
<li><strong>Skill portfolio management will become more difficult</strong> : For typical enterprise or ISV teams, the managers need to ensure adequate skill availability across all teams. As the number of languages in use increase, this management process will become harder. Which means there is an automatic economic disincentive which rises is in magnitude, each time you add yet another language to the mix.</li>
</ul>
<p>So is polyglotism good or bad ? I submit such a value attribute cannot be assigned to polyglotism per se. It needs to be really evaluated in your context, preferably beyond a project window into the medium or a long term. What is indeed obvious is that each new language will bring in some very strong capabilities and aspects where it is superior to the other languages in the mix. Equally obvious is that each new language will bring in associated costs. Just like there is no perfect language, there is no perfect number of languages that make sense in every context. Just like you do your homework in terms of language selection, make sure you do the same for your language portfolio not just in technology but in management and economic terms as well.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=nzPGzuOKpdU:vdzIIzxdPi4: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=nzPGzuOKpdU:vdzIIzxdPi4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=nzPGzuOKpdU:vdzIIzxdPi4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=nzPGzuOKpdU:vdzIIzxdPi4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=nzPGzuOKpdU:vdzIIzxdPi4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=nzPGzuOKpdU:vdzIIzxdPi4: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/nzPGzuOKpdU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/09/the-best-amount-of-polyglotism-is-that-you-can-manage-successfully/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/09/the-best-amount-of-polyglotism-is-that-you-can-manage-successfully/</feedburner:origLink></item>
		<item>
		<title>Mind your language: Pragmatic programmers should not be re-termed duct tape programmers</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/7R4802NuZKs/</link>
		<comments>http://blog.dhananjaynene.com/2009/09/mind-your-language-pragmatic-programmers-should-not-be-re-termed-duct-tape-programmers/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 05:17:43 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[programming]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=825</guid>
		<description><![CDATA[The Duct Tape Programmer by Joel Spolsky makes for an interesting reading. However it suffers from one issue. A big issue. It attempts to take terms with a particular well associated meaning with it, assign it to something else which already has a better available term and in the process creates one big ball of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.joelonsoftware.com/items/2009/09/23.html">The Duct Tape Programmer</a> by Joel Spolsky makes for an interesting reading. However it suffers from one issue. A big issue. It attempts to take terms with a particular well associated meaning with it, assign it to something else which already has a better available term and in the process creates one big ball of confusion.</p>
<p>In my understanding which hasn&#8217;t changed for many years &#8211; a duct tape programmer is a programmer who always takes the shortest route from point A to point B without giving regards to longetivity or maintainability of the solution. When he applies a duct tape &#8211; he is ticking off a job as &#8220;done&#8221;. He has not accounted for how long will the solution last. Is it even the right solution or is it just something that on the face of things seems right. He is only pragmatic enough to make sure he can get home early or be in his bosses good books. Thats where his pragmatism ends. Thats why the term has a negative meaning. Thats why it is not meant to be a compliment.</p>
<p>Now what happens when you associate it in the way Joel just did in his blog post ? Suddenly it no longer seems to be a negative term. It gives rise to confusion. If someone now calls me a duct tape programmer &#8211; I&#8217;ll be tempted to take it as a compliment. On the other hand &#8211; when someone writes a shitty crappy piece of code &#8211; I now have to figure out a new term &#8211; since I can no longer term it duct tape programming. I mean if I do and he responds a link to the post &#8211; what chance would I stand compared to someone as esteemed as Joel. </p>
<p>I understand as bloggers we want to make a point. I also understand that there are ways to make the point in a manner that really really stands out. But at times there are risks and negative consequences when we go down that path. These include confusing the juniors, the post getting misunderstood, misconstrued or even misquoted. These also include possible positive spin on essentially negative characteristics. Lets stick to calling pragmatic programmers as pragmatic programmers and leave duct tape programming to the realm of the essentially short sighted, fragile and often brittle programming that it really stands for.</p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/03/jerk-programmers-cant-be-managed-tactically/' rel='bookmark' title='Permanent Link: Jerk programmers can&#8217;t be managed tactically'>Jerk programmers can&#8217;t be managed tactically</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7R4802NuZKs:-97C_QDmADo: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=7R4802NuZKs:-97C_QDmADo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=7R4802NuZKs:-97C_QDmADo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7R4802NuZKs:-97C_QDmADo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=7R4802NuZKs:-97C_QDmADo:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7R4802NuZKs:-97C_QDmADo: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/7R4802NuZKs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/09/mind-your-language-pragmatic-programmers-should-not-be-re-termed-duct-tape-programmers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/09/mind-your-language-pragmatic-programmers-should-not-be-re-termed-duct-tape-programmers/</feedburner:origLink></item>
		<item>
		<title>Why should I switch to Scala ?</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/hZ-V1Chy6Fc/</link>
		<comments>http://blog.dhananjaynene.com/2009/08/why-should-i-switch-to-scala/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 15:33:44 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[scala]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=815</guid>
		<description><![CDATA[This post is a role-play and does not reflect my individual opinion about scala accurately. I am convinced about the capabilities and features of Scala along with the fact that it deserves the mantle of a long term replacement for Java. However language adoption goes beyond technical capabilities, and this post is a speculation on [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is a role-play and does not reflect my individual opinion about scala accurately. I am convinced about the capabilities and features of Scala along with the fact that it deserves the mantle of a long term replacement for Java. However language adoption goes beyond technical capabilities, and this post is a speculation on what a typical manager might be dealing with when attempting to decide whether to switch to Scala.</em></p>
<hr/>
<p>So I have been reading a lot about Scala lately and even opinions about how it will be a <a href="http://macstrac.blogspot.com/2009/04/scala-as-long-term-replacement-for.html">long term replacement for Java</a>. I&#8217;ve also read some interesting writeups about Scala adoption such as <a href="http://antoniocangiano.com/2009/08/07/on-scalas-future/">On Scala&#8217;s Future</a> and <a href="http://fupeg.blogspot.com/2009/08/tipping-point-for-scala.html">A Tipping Point for Scala</a>. While I used to code a lot, my responsibilities today require me to interact with and address a lot of issues including those faced by our customers, our development teams and also engage with my peers and superiors on many other difficulties bedeviling our organisation. This gives me little time to try out Scala. I know I should be doing that, but sincerely I do not have the time. So I rely on the feedback of my team, the trade journals and other influential architects within and outside my organisation.</p>
<p>I have heard about many developers switching from Java to Python / Ruby. However I have heard of relatively only a smaller number of large Java shops which have done the shift &#8211; most of the switch stories I&#8217;ve heard reflect a smaller sized teams. I can feel the excitement Scala has generated amongst the development teams &#8211; the brevity, the functional programming model introduction, the exciting stuff being done concurrently et al. I have no doubt that, given so much excitement it must really be a good language. </p>
<p>To introduce my organisation &#8211; it is one of those shops which service many projects concurrently. Given the tremendous business and growth, I must confess we do not always have the luxury of being able to hire the most top notch talent. We do have a lot of projects we use Java for, and thats a language our customers are comfortable with. I&#8217;ve had some of the senior people check out Scala to gain some feedback into the language. But at this stage I must say I am inclined to evaluate the shift but not convinced enough to do so. I am sure that I could if convinced drive the change to Scala incrementally.  However my fear stems from the fact that if things don&#8217;t turn out well, despite all the great advice I&#8217;ve received &#8211; its going to be my rear end on the line. So here&#8217;s some of my concerns regarding evaluating the shift to Scala and there are many of them, so some of you might be able to help me through this thought process.</p>
<ul>
<li><strong>Functional Programming : </strong> I&#8217;m sure in many ways it rocks. But my guys tell me they are not sure how to use it in the typical bread and butter applications which read from database, do some processing and write back to the database. Does Functional Programming help me in this context ? Will my team scale into being able to write functions with no side effects assuming thats a desirable goal ? What if they tie themselves up in knots and my release to the customer is risked ? I can&#8217;t afford that. Is functional programming even desirable in such contexts ? So I am not sure if in these contexts I should just ditch functional programming and work with just normal imperative programming capabilities of Scala. I am so confused, and afraid.</li>
<li><strong>Different Syntax :</strong> While Scala runs on the JRE, its syntax is very different from Java. From what I could gather, it is much easier for a Java programmer to read (make sense of) simple Python code than to read Scala code. Is it true ? So even if I do get compatibility in terms of the runtime environment, would I be picking up a language that is syntactically so different a language that it would involve a substantial relearning curve ? I remember when we had to learn Java and Javascript. For better or for worse these were indeed relatively minor modifications of the C/C++ syntax, compared to what I sense as the syntactic shift between Java and Scala. Am I wrong ? If so, could you help point me to resources which help me understand that Scala code is not much different than Java ?</li>
<li><strong>Sample code :</strong> Guys, I need your help. I need to see some good sample code. Some code which reflects how a typical application is architected, designed and programmed in Scala. And I don&#8217;t need it for a complex multi threaded actor based processing &#8211; I just need to see simple J2EE server based departmental applications maybe a simple recruitment tracking or library maintenance application. If I find a good one, I&#8217;ll just take it and give it to my team and say &#8211; there, thats how we&#8217;re largely going to build it, and even if we make a few changes along the way we at least have a reasonable template that we can build from.</li>
<li><strong>Dumbed down environment :</strong> I remember my great adventures with C and vi and make. But my team today is very different. They want great IDEs. They must have syntax highlighting, autocompletion and nice refactoring capabilities. If I ask them to move, some of them might be excited about the change and be willing to overcome these short term hurdles. But there are some of them who will not be keen to do so and may be disinclined to support such a shift. And at the end of the day my ability to conduct this shift is a function of my ability to carry a large proportion of them along with me. Even when I considered a shift from svn to git, the IDE support was a big issue even though quite obviously git capabilities were really exciting. I couldn&#8217;t push along that change, and in this case we are talking of changing the language.</li>
<li><strong>Is this a good time to shift to Scala ? </strong> I remember the early adopters of Java from 1996 thru 2001. While they gained a lot of experience, JRE and J2EE really matured only post JRE 1.3. Scala seems to be coming out with so many enhancements so fast, I am not sure if it has stabilised. I am told there is a 2.8 coming out in a few months. So if I train my team and Scala continues to change rapidly will I have to keep on retraining my team regularly ? And what about the customers I take to production. Will the frequent upgrades mean I end up supporting multiple customers on multiple versions of Scala ? Maybe Scala is stable but it would be helpful for someone important enough to make a clear statement that there are no new major shifts anticipated anytime soon and that these version shifts are likely to be no faster than the JRE version upgrades (which were fast enough).</li>
<li><strong>Support from peers and superiors :</strong> I remember the day I decided to shift to Java. What made the move easy for me was the sheer fact that Java was a big paradigm leap away from the then dominant C++. Not only was it cross platform with binary compatibility thrown in for good measure, Sun ensured that it made all the right noises to appeal to the enterprise architects and all the business managers. I see the senior developers in my team clamouring for the shift to Scala, but my peer managers and my superiors don&#8217;t display even the fraction of the enthusiasm they displayed during the Java shift. The implication for me is that the risk cover I get when I order the shift is far lesser than what I had when I made the move to Java. Which means if things don&#8217;t quite work out well, I&#8217;m really going to be screwed.</li>
<li><strong>Business friendliness : </strong> I understand all the nice talk about the technical excellence of Scala. But I really need to translate all these great language features into a projected ROI that I can use to convince others about. So I would like to see actual case studies of applications that were moved to Scala and what impact it had on the time and cost so that I can use it to compute my ROI. And what scares me is that learning curve may risk the initial applications long enough to push my breakeven point of shifting to Scala well beyond a 12 month and perhaps even a 24 month period. I fear things might not be as difficult but in absence of known studies, I am likely to lean towards projecting a worst case scenario rather than an optimistic one.</li>
</ul>
<p>So folks, I am asking for your help. And while a lot of you may think that people like us who balk at the thought of limited IDE support are wimps, please remember that 80% of us don&#8217;t fit into the top 20%. And if you would like Scala to be popular, you need us as much as we need you. And if you are not too sure, please remember Lisp and Smalltalk are great languages as well.</p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/04/a-brush-with-functional-programming-and-scala/' rel='bookmark' title='Permanent Link: A brush with Functional Programming and Scala'>A brush with Functional Programming and Scala</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=hZ-V1Chy6Fc:PN-ZZ3hwnuE: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=hZ-V1Chy6Fc:PN-ZZ3hwnuE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=hZ-V1Chy6Fc:PN-ZZ3hwnuE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=hZ-V1Chy6Fc:PN-ZZ3hwnuE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=hZ-V1Chy6Fc:PN-ZZ3hwnuE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=hZ-V1Chy6Fc:PN-ZZ3hwnuE: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/hZ-V1Chy6Fc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/08/why-should-i-switch-to-scala/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/08/why-should-i-switch-to-scala/</feedburner:origLink></item>
		<item>
		<title>CRUD is not only good for, but is the only consistent way to build REST over HTTP</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/ptAd_mpudwM/</link>
		<comments>http://blog.dhananjaynene.com/2009/08/crud-is-not-only-good-for-but-is-the-only-consistent-way-to-build-rest-over-http/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 08:35:45 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[rest]]></category>
		<category><![CDATA[crud]]></category>
		<category><![CDATA[interface]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=787</guid>
		<description><![CDATA[This is to comment on a perception forming that REST encourages exposing basic data elements through CRUD and that it encourages development of dumb applications (applications with shallow business logic).
Apart from some tweets I saw on the topic and some twitter conversations, the blog posts which perhaps set off the thought were

CRUD is bad for [...]]]></description>
			<content:encoded><![CDATA[<p>This is to comment on a perception forming that REST encourages exposing basic data elements through CRUD and that it encourages development of dumb applications (applications with shallow business logic).</p>
<p>Apart from some tweets I saw on the topic and some twitter conversations, the blog posts which perhaps set off the thought were</p>
<ul>
<li><a href="http://dobbscodetalk.com/index.php?option=com_myblog&amp;show=CRUD-is-bad-for-REST.html&amp;Itemid=29">CRUD is bad for REST</a> by Arnon Rotem-Gal-Oz</li>
<li>A summarisation of the same on InfoQ : <a href="http://www.infoq.com/news/2009/07/CRUDREST">Is CRUD bad for REST?</a></li>
<li><a href="http://hinchcliffe.org/archive/2009/08/06/17119.aspx">Can We REST For A Minute? 6 Lessons From The CRUD vs. Hypermedia Debates</a> by Dion Hinchcliffe</li>
</ul>
<p>The underlying fear and rationale for these posts makes a lot of sense &#8211; the fear of creating real dumb passive and shallow applications. I submit, that the problem however is not CRUD &#8211; it is resource identification and scoping, and CRUD is not only good for but is the right way to build intelligent, active and deep applications.</p>
<p><strong>CRUD supports Uniform Interface :</strong> The primary reason why CRUD gets used is because it supports a uniform interface. At the end of the day, a consistent Create/Read/Update/Delete or POST/GET/PUT/DELETE interface makes things easy. It makes things easy for the development team because of the consistency it introduces in their applications. It makes things easy for the clients who have a simple and consistent interface to deal with. At the interface level CRUD breeds consistency, and at the risk of broad generalisation, consistency is good.</p>
<p><strong>So why do we end up creating shallow applications at times with REST ? </strong> CRUD in general works with simple forms built on simple tables. Quite often this style of programming gets elevated into simple forms over simple domain objects. Standardised CRUD helps a lot at the lower end of application development and most database driven application developers are likely to have at some stage in their early development life attempted to build a small CRUD library or framework to help themselves substantially. The reason why we are likely to be ending up creating shallow applications is not because we apply CRUD, but because we continue to apply CRUD on tables or simple domain objects. And therein lie the distinctions</p>
<ul>
<li><em>REST is not about CRUD on tables &#8211; its about CRUD on resources</em></li>
<li><em>CRUD is the interface &#8211; not the implementation</em></li>
</ul>
<p>I attempt to bring up the difference in the example that I detail below.</p>
<p><strong>Simple Account Transfer Example</strong></p>
<p>Lets say we want to build the software to transfer amount X from account A into account B. Lets further specify that a transfer is not effected immediately and requires one more explicit approval. Lets also specify that while a transfer is waiting to be approved, it could be amended. Thats the simple scenario that we shall deal with.</p>
<p>In order to implement this, we shall define a datastructure / table / object for Account which shall contain a field called balance. Further there shall also be Transfer table / object which shall contain the fields sourceAccount, destinationAccount, amount and status. The possible status values shall be Initiated and Completed.</p>
<p>In a simple service oriented application we shall perhaps have a transfer service. Ignoring error handling, SOA wrapping etc., the service interface will probably boil down to the following equivalent Java interface.</p>
<pre name="code" class="java">
public interface TransferService
{
    public Long transfer (Long sourceAccountId,
                                Long destinationAccountId,
                                BigDecimal amount);
    public Transfer get(Long transferId);
    public void amend(Long transferId,
                             Long sourceAccountId,
                             Long destinationAccountId,
                             BigDecimal amount);
    public approve(Long transferId)
}
</pre>
<p>Lets think of these might get modeled in a REST environment. The important thing to remember is &#8211; don&#8217;t think about services or functions or methods &#8211; think about what are the resources you choose to expose using a simple CRUD interface.</p>
<p><span class="console"><br />
<font color="grey"># The following creates a new transfer. The returned data shall include<br />
# the URI of the new transfer, and the URI to approve it</font><br />
<font color="green">POST </font><font color="blue">/transfer </font><br />
<font color="grey"># The following retrieves the status of a current transfer. If it has not<br />
# been approved the returned data shall include the URI to approve it.</font><br />
<font color="green">GET </font><font color="blue">/transfer/${id}</font><br />
<font color="grey"># The following modifies the transfer. The returned data shall also<br />
# include the URI to approve it</font><br />
<font color="green">PUT </font><font color="blue">/transfer/${id}</font><br />
<font color="grey"># The following approves and further processes the transfer. It shall<br />
# return the URI for the transfer</font><br />
<font color="green">POST </font><font color="blue">/transfer/${id}/approve</font><br />
</span></p>
<p>While most of this seems all right &#8211; what sticks out like a sore thumb to me is the approve URI. Its just so SOAish / RPCish. Plus at least the way this particular interface has been implemented, there is no way to access  the approval specific information, without actually accessing the transfer. Hence I suggest that we define a new resource TransferApproval to account for the same.</p>
<p><span class="console"><br />
<font color="grey"># The following creates a new approval. If successfully executed<br />
# the transfer is complete and no future amendments or approvals<br />
# are allowed. the returned data shall include the TransferApproval<br />
# URI and the transfer URI</font><br />
<font color="green">POST </font><font color="blue">/transfer/${id}/approval</font><br />
<font color="grey"># The following gets an existing approval</font><br />
<font color="green">GET </font><font color="blue">/transfer/${id}/approval/${approvalId}</font><br />
</span></p>
<p>Please note that the &#8220;${approvalId}&#8221; at the approval URI simply wasn&#8217;t required &#8211; since there exists a 1-1 relationship with the transfer. I just included it for easier understanding. If I had to implement the functionality as is I would choose to skip it however if I knew I would very soon need to build in multi-stage approval (as in most banking systems), I would keep it so that each approval against a transfer can also be listed.</p>
<p>But the really interesting method above is the POST. This is a seemingly simple new (in RDBMS parlance) insert into TransferApproval table. But if you are building a REST service, you might be tempted to encourage your clients to not only create the new TransferApproval resource, but also go back and update the Transfer table to update a status to Approved. That would be a smell. Once the POST on the approval is processed, all side effects on other tables should be handled while servicing the POST request. In other words the POST request is not just an insert &#8211; its an insert with an associated trigger to conduct all the necessary downstream processing. And its essential one looks at request servicing in this manner so that CRUD can be used effectively. Servers should be designed this way, and clients should anticipate it and we should be on our way to build non-shallow applications.</p>
<p>So finally &#8211; <em>CRUD is good. It makes things easy for the clients. Stick to CRUD.</em> Just remember that it is CRUD on resources and not on tables, and the resources shall handle all the downstream changes necessary so that you don&#8217;t have to. And finally <em>CRUD is the interface, not the implementation</em>.</p>
<p>Note: Some might notice that this post is just a much more detailed elucidation of one of my earlier posts &#8211; <a href="http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/">REST is the DBMS of the internet</a>.</p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/' rel='bookmark' title='Permanent Link: REST is the DBMS of the Internet'>REST is the DBMS of the Internet</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ptAd_mpudwM:CVR6Lj-f_dA: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=ptAd_mpudwM:CVR6Lj-f_dA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=ptAd_mpudwM:CVR6Lj-f_dA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ptAd_mpudwM:CVR6Lj-f_dA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=ptAd_mpudwM:CVR6Lj-f_dA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=ptAd_mpudwM:CVR6Lj-f_dA: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/ptAd_mpudwM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/08/crud-is-not-only-good-for-but-is-the-only-consistent-way-to-build-rest-over-http/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/08/crud-is-not-only-good-for-but-is-the-only-consistent-way-to-build-rest-over-http/</feedburner:origLink></item>
		<item>
		<title>The Microsoft Word injunction has nothing to do with XML</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/B_02zu-Z0ew/</link>
		<comments>http://blog.dhananjaynene.com/2009/08/the-microsoft-word-injunction-has-nothing-to-do-with-xml/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 21:36:23 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[patents]]></category>
		<category><![CDATA[word]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=778</guid>
		<description><![CDATA[Obviously the development community is buzzing loudly about a injunction issued by a court against Microsoft disallowing it apparently from marketing Word. However what foxes me is that most articles give the impression that it is an issue with XML documents. As an example :

CNet.com : Judge orders Microsoft to stop selling Word
Crunchgear : Texas [...]]]></description>
			<content:encoded><![CDATA[<p>Obviously the development community is buzzing loudly about a injunction issued by a court against Microsoft disallowing it apparently from marketing Word. However what foxes me is that most articles give the impression that it is an issue with XML documents. As an example :</p>
<ul>
<li><a href="http://news.cnet.com/8301-10805_3-10308013-75.html">CNet.com : Judge orders Microsoft to stop selling Word</a></li>
<li><a href="http://www.crunchgear.com/2009/08/12/texas-judge-rules-microsoft-cant-sell-word-anymore/">Crunchgear : Texas Judge rules Microsoft can’t sell Word anymore</a></li>
<li><a href="http://techdirt.com/articles/20090811/2330285852.shtml">Techdirt.com : Judge Bars Sale Of Microsoft Word For Patent Infringement (Though It Won&#8217;t Stick)</a></li>
</ul>
<p>I also came across many other tweets bemoaning the verdict and expressing the opinion that it is a sad turn of events &#8211; it being related to storage of documents as XML. I did take a quick look at the said patent :<a href="http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&#038;Sect2=HITOFF&#038;p=1&#038;u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&#038;r=12&#038;f=G&#038;l=50&#038;co1=AND&#038;d=PTXT&#038;s1=5,787,449&#038;OS=5,787,449&#038;RS=5,787,449"> Patent 5787449</a>.</p>
<p>And therein I thought there&#8217;s seems to be a big misunderstanding (at least to my lay reading). The patent itself has nothing to do with storing data or documents or XML. Its got to do with a particular implementation of data storage which requires maintaining a <del datetime="2009-08-12T23:19:10+00:00">metadata</del><ins datetime="2009-08-12T23:19:10+00:00">metacode</ins> map. I shall use an example from the patent itself.</p>
<p>Lets say the XML is as follows :</p>
<blockquote><p>&lt;Chapter&gt;&lt;Title&gt;The Secret Life of Data&lt;/Title&gt;&lt;Para&gt;Data is hostile. &lt;/Para&gt;The End&lt;/Chapter&gt;</p></blockquote>
<p>The patent  suggests a storage which would maintain a metacode map as follows :</p>
<table>
<tr>
<th>Element Number</th>
<th>Element</th>
<th>Character Position</th>
</tr>
<tr>
<td>1</td>
<td>&lt;Chapter&gt;</td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>&lt;Title&gt;</td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>&lt;/Title&gt;</td>
<td>23</td>
</tr>
<tr>
<td>4</td>
<td>&lt;Para&gt;</td>
<td>23</td>
</tr>
<tr>
<td>5</td>
<td>&lt;/Para&gt;</td>
<td>39</td>
</tr>
<tr>
<td>6</td>
<td>&lt;/Chapter&gt;</td>
<td>46</td>
</tr>
</table>
<p>The metacode map essentially stores a tag along with its position. You can also see the same clearly on page 15 of the <a href="http://www.google.com/patents?id=y8UkAAAAEBAJ&#038;printsec=abstract&#038;zoom=4&#038;source=gbs_overview_r&#038;cad=0#v=onepage&#038;q=&#038;f=false">patent document on google patents</a>.</p>
<p>My reading suggests that the patent and alleged infringement if any has got nothing to do with storage of XML documents per se. In fact, that the tags being used are XML/SGML like is probably completely coincidental &#8211; these could very well be ${chapter} instead of &lt;chapter&gt;. And XML documents are stored with the tags embedded along with the content &#8211; this patent actually refers to maintaining a map of these tags and the positions they should be inserted into.</p>
<p>Could I be wrong in my interpretations ? Perhaps, since I haven&#8217;t seen anyone else point this out and would prefer to be corrected. But the fact remains that at this point in time as I write this post, I believe that XML and storage of XML documents are completely orthogonal to the patent and the case around it &#8211; that centers around a metacode map, and metacode maps are not a characteristic of typical XML storage at all. So there&#8217;s probably one big misunderstanding about what this case is about and if the injunction upsets you because you are against patents in principle, thats fair. But if you are disappointed about the possibility that this somehow substantially impacts XML storage, the way I interpret it &#8211; there&#8217;s no such implication.</p>
<p>I shall keep my fingers crossed and hope no one points out a seemingly obvious flaw in my interpretation.</p>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=B_02zu-Z0ew:gqCy5pUBMxw: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=B_02zu-Z0ew:gqCy5pUBMxw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=B_02zu-Z0ew:gqCy5pUBMxw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=B_02zu-Z0ew:gqCy5pUBMxw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=B_02zu-Z0ew:gqCy5pUBMxw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=B_02zu-Z0ew:gqCy5pUBMxw: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/B_02zu-Z0ew" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/08/the-microsoft-word-injunction-has-nothing-to-do-with-xml/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/08/the-microsoft-word-injunction-has-nothing-to-do-with-xml/</feedburner:origLink></item>
		<item>
		<title>Presentation : ReST explained</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/xrR-WUMcpI4/</link>
		<comments>http://blog.dhananjaynene.com/2009/07/presentation-rest-explained/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 09:05:13 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[rest]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=771</guid>
		<description><![CDATA[My presentation as a part of TechWeekend, Pune last Saturday. Note that it is a very long presentation. It was designed for a 3 hour slot and attempted to introduce ReST to users who had relatively little exposure to ReST.
ReST (Representational State Transfer) Explained
View more presentations from Dhananjay Nene.



No related posts.]]></description>
			<content:encoded><![CDATA[<p>My presentation as a part of TechWeekend, Pune last Saturday. Note that it is a very long presentation. It was designed for a 3 hour slot and attempted to introduce ReST to users who had relatively little exposure to ReST.</p>
<div style="width:600px;text-align:left" id="__ss_1690251"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/dnene/rest-representational-state-transfer-explained" title="ReST (Representational State Transfer) Explained">ReST (Representational State Transfer) Explained</a><object style="margin:0px" width="600" height="501"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rest-090707035705-phpapp01&#038;rel=0&#038;stripped_title=rest-representational-state-transfer-explained" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rest-090707035705-phpapp01&#038;rel=0&#038;stripped_title=rest-representational-state-transfer-explained" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="600" height="501"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" 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=xrR-WUMcpI4:crQ5kb2BA8w: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=xrR-WUMcpI4:crQ5kb2BA8w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=xrR-WUMcpI4:crQ5kb2BA8w:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=xrR-WUMcpI4:crQ5kb2BA8w:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=xrR-WUMcpI4:crQ5kb2BA8w:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=xrR-WUMcpI4:crQ5kb2BA8w: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/xrR-WUMcpI4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/07/presentation-rest-explained/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/07/presentation-rest-explained/</feedburner:origLink></item>
		<item>
		<title>Most american graduates are unemployable because …</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/46VuJ4PGKUw/</link>
		<comments>http://blog.dhananjaynene.com/2009/06/most-american-graduates-are-unemployable-because-.../#comments</comments>
		<pubDate>Tue, 23 Jun 2009 15:25:09 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[management]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[business processes]]></category>
		<category><![CDATA[innovation]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=748</guid>
		<description><![CDATA[Came across this post Top Indian CEO: Most American Grads Are ‘Unemployable’ leading to some substantial discussion (not all of it impassionate). I would first like to clarify that I am assuming the content in the post to be accurate based on the fact that other Indian sites are reporting that &#8220;No response or clarification [...]]]></description>
			<content:encoded><![CDATA[<p>Came across this post <a href="http://www.informationweek.com/blog/main/archives/2009/06/top_indian_ceo.html">Top Indian CEO: Most American Grads Are ‘Unemployable’</a> leading to some <a href="http://www.reddit.com/r/programming/comments/8uiuq/top_indian_ceo_most_american_grads_are/">substantial discussion</a> (not all of it impassionate). I would first like to clarify that I am assuming the content in the post to be accurate based on the fact that other Indian sites are reporting that &#8220;No response or clarification from Nayar has as yet been issued&#8221;. Moreover it is not targeted against Mr. Nayar or HCL but to the suggested thought process which attempts to make process orientation so critically important overriding many other qualities.</p>
<p>What perhaps hasn&#8217;t been clearly stated but is important is that that the standards for employability here are set by the employing organisation based on its context and preferences which may be different from standards required by many other organisations and I would submit that the statement ought to be looked at in that context as well.</p>
<p>To quote from the article :</p>
<blockquote><p>The official wanted to know why HCL, a $2.5 billion (revenue) company with more than 3,000 people across 21 offices in 15 states, wasn&#8217;t hiring more people in his state. Vineet&#8217;s short answer: because most American college grads are &#8220;unemployable.&#8221; (In fairness to HCL, the company recently announced plans to open a delivery center in another state, North Carolina, and invest $3.2 million and hire more than 500 employees there over the next five years under a Job Development Investment Grant.)</p>
<p>Many American grads looking to enter the tech field are preoccupied with getting rich, Vineet said. They&#8217;re far less inclined than students from developing countries like India, China, Brazil, South Africa, and Ireland to spend their time learning the &#8220;boring&#8221; details of tech process, methodology, and tools&#8211;ITIL, Six Sigma, and the like.</p>
<p>As a result, Vineet said, most Americans are just too expensive to train&#8211;despite the Indian IT industry&#8217;s reputation for having the most exhaustive boot camps in the world. To some extent, he said, students from other highly developed countries fall into the same rut.</p></blockquote>
<p>So why are some graduates are unemployable ?</p>
<p>Some of these are folks who are working on creating tons of new languages (Java, C#, Scala, Closure, Erlang, Python etc.), Operating Systems (Linux, Mac and Windows), frameworks for web applications, clustering, fault tolerance and scalability, schemaless and distributed databases to ensure availability and fault tolerance at a wide scale, competing messaging architectures that each service a particular problem differently etc. etc. Would you believe it some have set up clusters of  hundreds of thousands of machines and service search requests very rapidly. And some others are working on creating innovative and disruptive models in social networking, application integration, peer to peer networking etc. Many are working out next generation mobile technologies including building (not building on) android, iphone OS and the palm (whatever OS it has). And so many in their spare time are spending a whole bunch of time creating open source software, blogging and micro blogging about all the work they have done and sharing it with the wide world so that they can learn off it. And if these are consumer and technology stories, there are a whole bunch of people building critical business infrastructure architectures and frameworks and solutions as well. Even after you complete reading this post and come back to it a month from now, I shall still be busy trying to figure out what exactly India has been able to deliver that can challenge this. Of course let&#8217;s not miss out on the fact that most of these activities are conducted by fairly small sized teams. (I am aware some of the examples I quote could have non-american heritage, but that per se is not likely to detract from the issue)</p>
<p>Let&#8217;s call a spade a spade. When you have large or very large software construction and maintenance contracts, there are multiple ways to deal with it. In my experience, many Indian companiess have honed to a fine art the process of recruiting, deploying and juggling large armies of programmers to service such expectations (not all Indian companies are based on the same model). Many companies have indeed managed to acquire, retain and expand customer engagements through a combination of technology and business innovation. And they have done a good job of it in the context they&#8217;ve defined for themselves. In my limited understanding and experience it is not technology innovation, creativity or extraordinary technical prowess that is at the top of the list of skills that get deployed (though these are indeed found in sufficient levels across the board and some of the prowess can be impressive) &#8211; it&#8217;s the clockwork project management and business methodologies, techniques and innovation (and even these do result in projects with delays) with their reliance on &#8220;another brick in the wall&#8221; that gets the customer serviced.</p>
<p>So, if true, the &#8220;employable&#8221; was perhaps in that context.  If so based on the earlier two paragraphs, I submit it reflects positively and negatively on the employing organisation. Perhaps even more so than the graduates themselves. I do wonder if &#8220;incompatible&#8221; would have been a better choice of word. And I wonder what it reflected more poorly upon, as well who should be feeling more sad about it.</p>
<p><em>Disclaimer :</em> These views are mine, mine alone and should not be puported to be shared by any other people or companies I&#8217;ve been associated with in the past, present or the future.</p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/10/service-oriented-architecture-is-primarily-about-business-and-not-technology.-bollocks/' rel='bookmark' title='Permanent Link: Service Oriented Architecture is primarily about business and not technology. Bollocks!'>Service Oriented Architecture is primarily about business and not technology. Bollocks!</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/04/is-a-large-corporate-making-money-off-open-source-or-open-standards-an-oxymoron-in-a-sun-java-context/' rel='bookmark' title='Permanent Link: Is a large corporate making money off open source or open standards an oxymoron ? In a Sun / Java Context'>Is a large corporate making money off open source or open standards an oxymoron ? In a Sun / Java Context</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=46VuJ4PGKUw:ze_gx3blV-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=46VuJ4PGKUw:ze_gx3blV-o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=46VuJ4PGKUw:ze_gx3blV-o:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=46VuJ4PGKUw:ze_gx3blV-o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=46VuJ4PGKUw:ze_gx3blV-o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=46VuJ4PGKUw:ze_gx3blV-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/46VuJ4PGKUw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/06/most-american-graduates-are-unemployable-because-.../feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/06/most-american-graduates-are-unemployable-because-.../</feedburner:origLink></item>
		<item>
		<title>Opera Unite : A model for server disintermediation on the internet</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/jdjwIJfbTgw/</link>
		<comments>http://blog.dhananjaynene.com/2009/06/opera-unite-a-model-for-server-disintermediation-on-the-internet/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 09:22:14 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[Internet and Social Media]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[software]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=737</guid>
		<description><![CDATA[Since Opera Unite got introduced a couple of hours ago. I had a chance to do a quick review of the functionality. As I begin to play with it, couldn&#8217;t but help write a short post on what it seems to be doing.
Here&#8217;s what my preliminary look into Opera Unite suggested :

It has a web [...]]]></description>
			<content:encoded><![CDATA[<p>Since <a href="http://unite.opera.com/">Opera Unite</a> got introduced a couple of hours ago. I had a chance to do a quick review of the functionality. As I begin to play with it, couldn&#8217;t but help write a short post on what it seems to be doing.</p>
<p>Here&#8217;s what my preliminary look into Opera Unite suggested :</p>
<ul>
<li>It has a web server bundled into the browser.</li>
<li> It allows you to write (what would be in current parlance be called) serverside apps using javascript which are hosted by the web server.</li>
<li> Sample applications include photosharing apps to share photos on your desktop or fridge which allows internet users to post notes to you.</li>
<li> It allows these apps to be accessed across a router on a dynamic IP using a subdomain on a centralised operaunite service ..operaunite.com (not sure yet whether across a firewall as well but seems so)</li>
<li> It allows these applications to be shared / published using the config.xml file (similar to google widgets ?). There&#8217;s also a central opera directory for the same, but I don&#8217;t think sharing is restricted to that service alone (apple are you listening ?)</li>
<li> These applications can be further installed by other users of Opera Unite (which is the web server service running inside the Opera browser).</li>
</ul>
<p>So why is this such a big deal ? Without going into any further elaboration let us just imagine user&#8217;s used it for following (for desktop-to-desktop or peer-to-peer) communication :</p>
<ul>
<li>Send mails to each other &#8211; disintermediates email services</li>
<li>Send short burst messages to each other &#8211; potentially disintermediates twitter</li>
<li>Share files with each other &#8211; disintermediates ftp servers and shares characteristics with gnutella, kazaa etc.</li>
<li>Share resume, product profiles etc. &#8211; disintermediates traditional static web hosts</li>
<li>Build networks of other interested users &#8211; disintermediates linkedin, facebook</li>
</ul>
<p>The constraint it introduces is that there is no global list of user ids to search from &#8211; you need to know the URL upfront (like the facebook vanity URL). </p>
<p>The possibilities are many. As are the interesting uses this model could be put to. And the characteristics of improved privacy, data ownership and control (including fine grained access control or selectivity). And there does remain a potential for malicious actors and virus writers to ride on popular apps to exploit vulnerabilities to tend to their nefarious needs.</p>
<p>As I put it differently in another tweet &#8211; this opens up the possibility for a google wave without the google in it.</p>
<p><strong>References :</strong></p>
<ul>
<li><a href="http://labs.opera.com/news/2009/06/16/">Taking the web into our hands one computer at a time</a> : An introductory writeup</li>
<li><a href="http://dev.opera.com/articles/view/an-introduction-to-opera-unite/">An introduction to Opera Unite</a> : A get started guide</li>
<li><a href="http://dev.opera.com/articles/view/opera-unite-developer-primer/">Opera Unite developer&#8217;s primer</a> : A primer for writing server side applications</li>
</ul>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/' rel='bookmark' title='Permanent Link: Design Characteristics of REST / Resource Oriented Server Frameworks and Clients'>Design Characteristics of REST / Resource Oriented Server Frameworks and Clients</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=jdjwIJfbTgw:cTNHntZj0f0: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=jdjwIJfbTgw:cTNHntZj0f0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=jdjwIJfbTgw:cTNHntZj0f0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=jdjwIJfbTgw:cTNHntZj0f0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=jdjwIJfbTgw:cTNHntZj0f0:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=jdjwIJfbTgw:cTNHntZj0f0: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/jdjwIJfbTgw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/06/opera-unite-a-model-for-server-disintermediation-on-the-internet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/06/opera-unite-a-model-for-server-disintermediation-on-the-internet/</feedburner:origLink></item>
		<item>
		<title>Improve your web based software development and maintenance ROI with dynamic programming languages</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/pwOzh8TLDEE/</link>
		<comments>http://blog.dhananjaynene.com/2009/06/improve-your-web-based-software-development-and-maintenance-roi-with-dynamic-programming-languages/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 07:43:53 +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[scala]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[dynamic languages]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=725</guid>
		<description><![CDATA[This is a cross post of my article which appeared in PuneTech in March 2009 here. The article is reproduced verbatim including the editor&#8217;s notes (in italics). I had already posted the slides referred to in the talk that was proposed in this article in the blog postTalk Slides : Programming Language Selection.
After we carried [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a cross post of my article which appeared in <a href="http://punetech.com">PuneTech</a> in March 2009 <a href="http://punetech.com/improve-your-web-based-software-development-and-maintenance-roi-with-dynamic-programming-languages/">here</a>. The article is reproduced verbatim including the editor&#8217;s notes (in italics). I had already posted the slides referred to in the talk that was proposed in this article in the blog post<a href="http://blog.dhananjaynene.com/2009/03/talk-slides-programming-language-selection/">Talk Slides : Programming Language Selection</a>.</em></p>
<hr /><em>After we carried a few quick articles on <a href="http://punetech.com/why-you-need-to-learn-ruby-and-rails/">why you should learn more about Ruby and Ruby on Rails</a> (<a href="http://punetech.com/why-you-need-to-learn-ruby-and-rails/">take 1</a>, <a href="http://punetech.com/why-ruby-is-cool-take-2/">take 2</a>) last month, we decided that we wanted to give people a much deeper article on why these new languages (Ruby, Python, PHP) and frameworks (Rails, Django) are setting the web world on fire. We invited <a href="http://punetech.com/wiki/Dhananjay_Nene">Dhananjay Nene</a> to write an article with an in depth discussion of the technical reasons how these new languages differ from the older ones and when to choose one over the other. He responded with this article which, as an added bonus, also includes the business reasons for your decisions. At the <a href="http://twitter.com/d7y/statuses/1267599217">request of the community</a>, Dhananjay is also <a href="http://upcoming.yahoo.com/event/2166183">giving a talk on the relative strengths and weaknesses of different programming languages</a> on Saturday, 28th March, 4pm, at SICSR. All those who found this article interesting should definitely attend.<br />
</em></p>
<h3>Introduction</h3>
<p>Programing language selection is often a topic that elicits a lot of excitement, debate and often a bit of acrimony as well. There is no universally superior programming language that one can recommend, so I tend to generally disregard most language opinions which say ‘X language is the best’, without specifying the context under which it is superior. Finally most language debates often deal with the technical issues and not the ROI issues. Hopefully I shall be able to address this topic without being guilty of any of these problems.</p>
<div>
<p><strong>So what languages are we referring to here ?</strong></div>
<div style="margin: 1em; display: block;">
<div>
<dl style="width: 152px;">
<dt><a href="http://en.wikipedia.org/wiki/Image:Ruby-%28programming-language%29-logo-2008.png"><img title="Official Ruby logo" src="http://upload.wikimedia.org/wikipedia/en/d/de/Ruby-%28programming-language%29-logo-2008.png" alt="Official Ruby logo" width="142" height="163" /></a></dt>
<dd style="font-size: 0.8em;">Image via <a href="http://en.wikipedia.org/wiki/Image:Ruby-%28programming-language%29-logo-2008.png">Wikipedia</a></dd>
</dl>
</div>
</div>
<p>The range of languages that fall under <a href="http://en.wikipedia.org/wiki/Dynamic_programming_language#Languages" target="_blank">Dynamic Programming Languages</a> category is rather extensive. My experience is primarily limited to <a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29" target="_blank">Python</a> and to a lesser extent <a href="http://en.wikipedia.org/wiki/PHP" target="_blank">PHP</a>, <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29" target="_blank">Ruby</a>, <a href="http://en.wikipedia.org/wiki/Javascript" target="_blank">Javascript</a>, and <a href="http://en.wikipedia.org/wiki/Groovy_%28programming_language%29" target="_blank">Groovy</a>. For the rest of this article, I shall be primarily referring to Python or Ruby when I use the word dynamic languages, though many of the references may continue to be applicable and relevant for a number of other <a title="Dynamic programming language" rel="wikipedia" href="http://en.wikipedia.org/wiki/Dynamic_programming_language">dynamic programming languages</a>.</p>
<p>As I describe the technical characteristics, I shall also continue to attempt to address the business aspects as well, so you might find this article at a little techno-business level. Assuming I am able to excite their interest, the tech guys would not find sufficient technical details and would be hungry to hunt for more, and while the business guys would get a little teased with the possibilities, they will not quite get the ROI served in the traditionally formatted excel spreadsheets. Being aware of that, I continue down this path with a feeling that this perhaps will be the most appropriate level for me to abstract this article to.</p>
<div>
<h3>Characteristics of Dynamic Programming Languages.</h3>
<p>Let us quickly review some of the characteristics :</p></div>
<div style="margin: 1em; display: block;">
<div>
<dl style="width: 212px;">
<dt><a href="http://en.wikipedia.org/wiki/Image:Python_logo.svg"><img title="CPython" src="http://upload.wikimedia.org/wikipedia/en/thumb/0/06/Python_logo.svg/202px-Python_logo.svg.png" alt="CPython" width="202" height="48" /></a></dt>
<dd style="font-size: 0.8em;">Image via <a href="http://en.wikipedia.org/wiki/Image:Python_logo.svg">Wikipedia</a></dd>
</dl>
</div>
</div>
<p><strong><a href="http://en.wikipedia.org/wiki/Object-oriented" target="_blank">Object Oriented</a> :</strong> Many dynamic languages support full object orientation. There are many who don’t necessarily buy the benefits of Object Orientation, but it is my strong belief, that once a piece of software grows beyond a certain threshold of complexity and / or size, Object Orientation starts delivering very strong dividends. There are a few areas such as highly complex, algorithmic processing which might be better suited for functional programming. However a majority of the medium-to-large sized web applications are better served by OO. The empirical evidence at least bears out the fact that most of the most popular languages today (except C) are Object Oriented. However this still is a very very large class of languages which in them include <a title="C++" rel="wikipedia" href="http://en.wikipedia.org/wiki/C%2B%2B">C++</a>, Java, PHP, Python, Ruby etc. The one area where some dynamic languages separate themselves from the others is in the notion of “everything is an object”, ie. primitives such as numbers, functions are all objects by themselves.</p>
<p><em>Business implications:</em> OO code well designed and implemented allows for a substantial reduction in maintenance costs. When working with a team which is up the curve on OO, it is likely to lead to lower costs and time on inital coding as well. On the other hand, both training costs and skill requirements are higher for fully OO languages. If you are already using partialy OO / hybrid languages such as PHP, C++ or Java, and are convinced about OO, using fully OO languages such as Python or Ruby will help you leverage the OO capabilities even further.</p>
<p><strong><a href="http://en.wikipedia.org/wiki/Duck_typing" target="_blank">Duck Typing</a> :</strong> In very loose terms, duck typed languages do not require you to declare an explicit interface. You send an object a message (ie. invoke a function or access an attribute) and if it can respond to it, it will, and if it can’t it will result in an error. Duck typing is a specific typing system which is a subset of a broader system called Dynamic Typing, which often makes for an interesting debate with its counterpart &#8211; Static typing : <a href="http://en.wikipedia.org/wiki/Dynamic_typing#Static_and_dynamic_type_checking_in_practice" target="_blank">Static and Dynamic Type checking in practice</a>. For people well grounded in static typing alone, this can sometimes seem to be sacrilegious. I am convinced that duck typing makes writing code much much faster for two reasons &#8211; a) You now require to write fewer lines of code and b) You often don’t have to keep on regularly waiting for the compiler to do its work. There is also a substantial capability enhancement that dynamic typing makes to the language type system, which allow the frameworks to build dynamic types on the fly. This in turn offers the framework users many more capabilities than frameworks written in other languages. That is why it is nearly impossible to write frameworks like Rails or Django in Java (You can modify the class loaders and use byte code generation to generate the new types, but the compiler can’t see them so you cant use them). That is also why there is a lot of anticipation of using <a title="JRuby" rel="homepage" href="http://jruby.codehaus.org/">JRuby</a>, <a title="Jython" rel="homepage" href="http://www.jython.org/">Jython</a> and <a title="Grails (framework)" rel="homepage" href="http://grails.org/">Grails</a> on the <a title="Java Virtual Machine" rel="wikipedia" href="http://en.wikipedia.org/wiki/Java_Virtual_Machine">JVM</a> since the languages underlying them (Ruby, Python and Groovy respectively) bring the dynamic typing capabilities to the JVM platform.</p>
<p><em>Business Implications :</em>Writing code is much much faster. Maintenance depending upon the situation can sometimes be more or less difficult in case of dynamic typed languages. Refactoring is usually a lot more difficult in case of <a title="Type system" rel="wikipedia" href="http://en.wikipedia.org/wiki/Type_system">dynamically typed</a> languages since the underlying type system is not able to infer sufficiently about the code to help the refactoring tools, as is possible in case of statically typed languages. It is my opinion that a skilled and trained development team using dynamic languages can generally substantially outperform another equally capable team using static languages. Insufficiently or poorly skilled development teams however can lead to very very different kind of pitfalls in these class of languages. In both cases the code becomes difficult to change or maintain due to a) cryptic code in case of dynamically typed languages and b) extremely large code bases in case of statically typed languages. Both are undesirable situations to be in but if I had to choose between one of the two, I would go for being in the cryptic mess since it is at least manageable by bringing in external skilled help.</p>
<div>
<p><strong>Metaprogramming :</strong> Metaprogramming is in loose terms the ability of programs to write programs. A large proportion of developers may not use this capability too frequently. Specifically in web application development it gets used as a mechanism to transform one set of datastructures which a programmer specifies into code at runtime. As I point out later in this article, it in fact is a very important element in designing common frameworks and libraries which in turn offer substantial capabilities including small code and easier maintenance. A quick note to state that metaprogramming is not code generation. In case of code generation, one uses the generator to generate code which is then compiled. A big limitation with this is the fact that often people modify the generated code leading to really tough maintenance nightmares and the fact that it is a two stage process which is prone to more errors. Metaprogramming results in new code “coming to life” so to speak while your program is running.</div>
<p><em>Business Implications :</em> Read on, they will get covered in the final roundup. They are large and they are positive.</p>
<div>
<p><strong>Function blocks/objects, iterators, closures, continuations, generators: </strong> I will not go into any substantial details of this issue except to say that small pieces of code logic can be handled in a much much more concise way than if these weren’t supported. While many situations may not need closures support, you will be glad to have them on your side when needed.</p>
<p><em>Business Implications : </em> Helps having shorter, cleaner code leading to lesser development and maintenance costs. Another significant positive is that your developers are just likely to be so much happier since they get some truly nice building blocks for concise and elegant expression of their logic. Can’t think of any significant negatives.</p>
<p>There are a full range of other capabilities, but none come to mind immediately as something that have strong business implications as well.</p>
<h3>The role of frameworks</h3>
</div>
<div style="margin: 1em; display: block;">
<div>
<dl style="width: 212px;">
<dt><a href="http://commons.wikipedia.org/wiki/Image:Ruby_on_Rails_logo.jpg"><img title="Ruby on Rails" src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Ruby_on_Rails_logo.jpg/202px-Ruby_on_Rails_logo.jpg" alt="Ruby on Rails" width="202" height="240" /></a></dt>
<dd style="font-size: 0.8em;">Image via <a href="http://commons.wikipedia.org/wiki/Image:Ruby_on_Rails_logo.jpg">Wikipedia</a></dd>
</dl>
</div>
</div>
<p>When did these languages say Ruby and Python originate ? Most people are likely to be a little surprised if the answer is in the last millenium. Yet Guido von Rossum started working on Python in 1986 and Ruby was released in 1992. Python has been rather well known within the scientific community and perhaps a bit within the systems / OS utility programming communities for quite some time. However both languages grabbed a large mindshare only post 2005. A big reason for their popularity (especially in case of Ruby’s case) came from the popularity the frameworks which used them. <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> for ruby and <a href="http://www.djangoproject.com/" target="_blank">Django</a> (to the best of my knowledge) for python. These frameworks combined the language capabilities with the learnings of good design practices for internet applications (eg MVC, declarative validations, simple ORM etc) into a simple usable package, which developers could take and build web applications quickly. There are examples of people having built simple web apps within a day and medium complexity apps in 1-3 weeks using these frameworks. The languages are the ingredients, the frameworks are the cooks &#8211; a great combination for serving great meals. Now you will find many such frameworks in these languages, including some which have better capabilities for building more sophisticated / complex applications eg. <a href="http://merbivore.com/" target="_blank">Merb</a> and <a href="http://www.pylonshq.com/" target="_blank">Pylons</a>.</p>
<p>I am not too sure of how many people are exactly aware of the role of metaprogramming in the frameworks’ successes. I am willing to believe that but for metaprogramming, these frameworks simply would not have achieved anywhere close to the success they achieved. It is metaprogramming which takes the datastructures as defined by a developer and converts it into runtime code implicitly, saving the developer lots of time and effort. So even if most developers don’t actively write metaprograms, their lives are so much easier. Metaprogramming capabilities are also the reason why it is virtually impossible to write similar frameworks in Java. However if you are on the .NET or JVM environments, things are definitely looking encouraging with the possibilities to use IronPython or IronRuby on .NET or JRuby or Jython or Groovy+Grails on the JVM.</p>
<p><em>Business implications :</em> If you are focused on scientific or desktop or highly algorithmic applications, where python especially is used extensively, you are likely to get benefits from these languages on their own merit alone. For web applications you will see the maximum benefits by using the web MVC frameworks along with the languages. I submit that on the whole you are likely to see very substantial reduction in development, enhancement and maintenance times &#8211; sweet music for any end user, investor or project manager.</p>
<h3>Increased Business Agility</h3>
<p>There is one more reason why I believe these languages are especially helpful. They help by increasing development agility to an extent where it now allows for the business to be more agile. You can get a first prototype version up in weeks, take it around to potential users, and gather feedback on the same. Incorporate elements of this feedback into the next release of working code quickly. The business benefits of such a scenario are tremendous. You might wonder that this is a process issue, so what does it have to do with a language selection. I would submit, that languages which allow changes to be made faster, help support this process in a far superior way. Another equally important facet is the superior risk management. Since you are able to build features with lower investments, you are able to get a series of customer feedbacks into your decision making process much faster. This helps being able to come up with a product that really meets the customer expectations much earlier. This happens by allowing the better features to come in earlier and also by allowing the lesser important or lesser relevant features to be decided to be deferred earlier. That’s precisely the reason why the dynamic languages have found a strong acceptance in the startup world. I believe the increasing agility which is often required in the startup world, is and will continue to be increasingly required of established enterprises. Precisely the reason why I believe these languages will continue to do better in the enterprise space as well. Finally, these languages make it relatively easier to tell your business sponsor &#8211; We will work with you on imprecise requirements rather than spending months on nailing down requirements which anyways are likely to change later. This has both a pro and a con especially for outsourcing situations. It is likely to allow for tremendous customer delight in terms of a vendor that works with him in such a flexible manner, yet it does introduce challenges in terms of how the commercials and management of the project are handled.</p>
<p>The reason I would like to especially point out increased business agility is because programmers don’t often visualise or evangelise it much, but when I wear a manager’s hat, it is perhaps the most compelling benefit of these languages.</p>
<div>
<h3>Concluding</h3>
<p>As I said earlier, there is no single universal language which is the best for all scenarios. There are some scenarios where using dynamic languages will not be helpful</p>
<div><a href="http://radar.oreilly.com/2009/02/state-of-the-computer-book-mar-22.html"><img src="http://farm4.static.flickr.com/3569/3377871146_700f422281_o.jpg" alt="Programming language book sales 4Q2008" /></a></p>
<div>A Treemap view of sales of programming language books by O’Reilly Media in 4Q2008. The size of a box represents the total sales of a book. The color represents the increase or decrease in sales compared to same quarter in 2007. Green = increase, bright green = big increase, red = decrease, bright red = large decrease. See <a href="http://radar.oreilly.com/2009/02/state-of-the-computer-book-mar-22.html">full article at O’Reilly Radar</a> for lots of interesting details.</div>
</div>
<p><strong>When not to use these languages</strong></div>
<ul>
<div>
<li>You are building a simple / small application and don’t have the available skill sets. One exception to this is where you decide to use it in a simple application to allow yourself a non risky mechanism of building these skillsets.</li>
</div>
<div>
<li>Extremely High performance requirements. However please make sure that you really need the high performance capabilities of say a C, C++ or Java. In my experience 80% of developers like to believe that they are building highly performant applications where the maximum speed is a must have. Yet the top 10% of them are facing far far more critical performance requirements than the remainder. Unless you are convinced you are in the top 10%, you should certainly consider dynamic languages as an option. Moreover in case of most high performance requirements, these can sometimes be boiled down to a few inner loops / algorithms. Consider implementing the same in C, / Java or other .NET languages (depending upon the choice of your dynamic language interpreter implementation)</li>
<li>You have an architecture standard in place which does not allow using these languages. If you are convinced your applications are better served by using dynamic languages both from your individual application and an overall enterprise perspective, consider taking the feedback to your standards setting body to see if you can pilot a different approach. Also evaluate if the .NET or JVM versions can help you comply with the architecture guidelines.</li>
<li>You are unable to commit to the retraining requirements. While these languages are easy and powerful to use, leveraging that power can require some amount of retraining. If that does not fit your business plans, since the retraining effort could impact immediate and urgent requirements, that could be a reason to not use these languages. However in such situations do consider investing in building this skill sets before you get to another similar decision point.</li>
</div>
<li>You need a very high levels of multithreadinging as opposed to multi processing support. While this is not a typical situation for web applications, you should be aware that most dynamic languages have some limitations in terms of multi threading support. This actually is not necessarily an issue with the language as with the implementation eg. the C implementation of python has the notorious Global Interpreter Lock which constrains you from being able to use more than a handful of threads per processes efficiently. However the same restriction is not present in Jython (the jvm implementation of python). This is likely to be an issue for a miniscule percentage of the web applications market for the primary reason that multi process / shared nothing architecture styles often work quite well for many web applications and they don’t really need multi threading.</li>
</ul>
<div>
<p><strong>So where’s my return on investment ?</strong></div>
<p>First of all lets talk of the investment part. If you get into it in a paced approach, the investment may not be that great. Start with a team size of anywhere between 2-6 people (depending upon your organisation and project size). Think of 15 days of intensive training followed by a 2-6 months coming up the curve effort (more likely 2 than 6). Make sure your first project is not a critical one under tremendous business pressure. This can be subsequently followed by more people getting retrained as necessary. In the longer term it might actually help reduce your incremental investment, since it might be much easier to ramp up new programmers in Ruby or Python than say Java or C#.</p>
<p>Secondly lets look at the incrementally higher costs. You are likely to need people who are a little bit more capable in terms of understanding and debugging the same logic expressed in fewer lines of code (that sometimes can be a challenge) and then be able to modify and enhance the same. This may increase your testing and fixing costs in the earlier days. Finally while the fewer lines of code can make refactoring easier, you could find that your total refactoring costs are a little higher.</p>
<p>Now the returns part. I am convinced that the increased business agility is the strongest return in business terms. Immediately after that is the substantial reduction in development, enhancement and maintenance times. If neither of these benefits are appealing, when contrasted with some other issues that you might perceive, maybe considering dynamic languages in your context is not such a great idea.</p>
<p>One more factor that I would of course encourage you to evaluate from a business perspective are the implications for you if your competition (assuming it is not already using them) started using these languages. The implications would vary from case to case, but it could also help you decide how important this issue is for you.</p>
<h3><em>About the author &#8211; Dhananjay Nene</em></h3>
<p><em>Dhananjay is a Software Engineer with around 17 years of experience in the field. He is passionate about software engineering, programming, design and architecture. He did his post graduation from Indian Institute of Management, Ahmedabad, and has been involved in Senior Management positions and has managed team sizes in excess of 120 persons. His <a href="http://blog.dhananjaynene.com/">tech blog</a>, and <a href="http://twitter.com/dnene">twitter stream</a> are a must read for anybody interested in programming languages or development methodologies. Those interested in the person behind the tech can check out his <a href="http://dhananjay.nene.in/">general blog</a>, and <a href="http://twitter.com/d7y">personal twitter stream</a>. For more details, check out <a href="http://punetech.com/wiki/Dhananjay_Nene">Dhananjay’s PuneTech wiki profile</a>.</em></p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/03/talk-slides-programming-language-selection/' rel='bookmark' title='Permanent Link: Talk Slides : Programming Language Selection'>Talk Slides : Programming Language Selection</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/04/a-brush-with-functional-programming-and-scala/' rel='bookmark' title='Permanent Link: A brush with Functional Programming and Scala'>A brush with Functional Programming and Scala</a></li>
<li><a href='http://blog.dhananjaynene.com/2010/01/software-development-is-about-the-middle-and-not-just-the-end/' rel='bookmark' title='Permanent Link: Software development is about the middle and not just the end'>Software development is about the middle and not just the end</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=pwOzh8TLDEE:rqvq9jrYY6w: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=pwOzh8TLDEE:rqvq9jrYY6w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=pwOzh8TLDEE:rqvq9jrYY6w:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=pwOzh8TLDEE:rqvq9jrYY6w:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=pwOzh8TLDEE:rqvq9jrYY6w:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=pwOzh8TLDEE:rqvq9jrYY6w: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/pwOzh8TLDEE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/06/improve-your-web-based-software-development-and-maintenance-roi-with-dynamic-programming-languages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/06/improve-your-web-based-software-development-and-maintenance-roi-with-dynamic-programming-languages/</feedburner:origLink></item>
		<item>
		<title>Musings on REST</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/7vsdzANqAOo/</link>
		<comments>http://blog.dhananjaynene.com/2009/06/musings-on-rest/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 00:16:41 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[rest-musings]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=710</guid>
		<description><![CDATA[This is a summarisation of a four part series of posts I wrote on REST over the past week. This post lists each of them along with a very high level summary and a small snippet from each hopefully sufficient enough to tickle your thoughts and interests.

Why REST ?This is a rather long post which [...]]]></description>
			<content:encoded><![CDATA[<p>This is a summarisation of a four part series of posts I wrote on REST over the past week. This post lists each of them along with a very high level summary and a small snippet from each hopefully sufficient enough to tickle your thoughts and interests.</p>
<ol>
<li><strong><a href="http://blog.dhananjaynene.com/2009/06/why-rest/">Why REST ?</a></strong>This is a rather long post which provides a narrative of the history of web and service architectures eventually coming together into web services. It refers to many of the strengths that made web architectures so omnipresent, and to the uneasy coming together of the two architectures as web services. It details many REST characteristics, describes how REST provided a style by which the strengths of the web architectures could be retained even as the processing aspects of service architectures could be supported, and finally enumerates some of the benefits of REST.
<p><strong>On the coming together of Web and Service oriented architectures.</strong></p>
<blockquote><p>Clearly as WWW started getting used far more, people were only too keen to use it for much more than storing or retrieving documents. This led to the development of CGI and subsequently other dynamic web application technologies (eg. LAMP, J2EE etc.) which would allow us to use the web to ‘do something’. Since these were clearly offshoots of the SOA world, being mapped onto the WWW infrastructure, the characteristics of such dynamic applications often had a lot in common with SOA, and they started dropping many characteristics of the traditional static WWW. Thus was born the child of the world wide web and distributed service oriented architectures – web services. This led to newer SOA technologies such as WS-* and SOAP.</p>
<p>Like the typical scenarios after the discovery of any highly profitable opportunity, the early rush was to leverage the opportunity and it was only a little later when the dust died down, that people started wondering if they had sacrificed something in the heat and dust of the moment. That stock taking resulted in the realisation, that some of the very basic characteristics of the extraordinarily successful internet technologies (FTP / SMTP / WWW) had been diluted, and even if such dilution still allowed immediate progress to have occurred, some of them would need to be corrected to be able to continue the explosive growth that had been seen so far. One such exercise in my opinion is the laying down of the REST architecture style.</p></blockquote>
<p><strong>On the aspect that even though REST is not as feature rich as SOA, its strength is the simpler abstractions it employs</strong></p>
<blockquote><p>I have generally found that simpler abstractions even though harder to deal with initially, often win in the long run. Notice the fact that the bare bones rendering functionality of HTML/WWW completely trounced the rich UI and application integration capabilities then available (eg. Windows/Java and DCOM/CORBA/RMI). This is not to suggest that the extra capabilities are not required. That is why Rich User Interfaces on WWW continue to be a dominant part of the internet technology wishlist. However the simpler, cleaner and minimalistic abstractions often are far more important than feature richness. A point I would want to make in favour of REST even as I admit that conventional SOA technologies are far more feature rich than REST.</p></blockquote>
</li>
<li><strong><a href="http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/">REST is the DBMS of the Internet</a></strong>This post reflects the thought that since REST effective allows one to GET, PUT, POST and DELETE resources, it is similar to being a database which exposes its tables to many applications to SELECT, INSERT, UPDATE and DELETE from. In this analogy, each media type is effectively a new table and the REST interface is primarily of the nature of allowing basic operations on a set of tables (resources).<br />
<blockquote><p>To summarise the exchange differently<br />
<em><br />
“If WS-* is the RPC of the Internet, REST is the DBMS of the internet“</em></p>
<p>To expand on it a bit more :</p>
<p>Traditional SOA based integration visualises different software artifacts being able to interact with each other through procedures or methods. REST effectively allows each software artifact to behave as a set of tables, and these artifacts talk to each other using SELECT, INSERT, UPDATE and DELETE. (or if you wish GET, PUT, POST, DELETE). And where exactly is is the business logic ? Is it in the stored procedures ? Not Quite. Its in the triggers.</p></blockquote>
</li>
<li><strong><a href="http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/">Design Characteristics of REST / Resource Oriented Server Frameworks and Clients</a></strong>This post dwells into the many aspects of design of a REST or Resource Oriented Serverside Framework and attempts to enumerate a large number of their characteristics. One of the aspects it brings up is the role of the Controller. Since the a resource oriented interface primarily consists of basic primitive operations on resources, it suggests that the controller could either be merged with the Resource or support only basic operations and have a one to one relationship with a resource.<br />
<blockquote><p>This is where a potential differences with conventional frameworks arise. If I was to think of it from an EJB like perspective, I would model a OrderController as a Session bean and a Order as an entity bean. In case of lightweight POJO based model, I would have an OrderController as the endpoint exposed by say using Struts and model the Order as a entity POJO and map it to the database using Hibernate. In other non java frameworks, I would have a class to represent an OrderController and another one to represent the order along ActiveRecord pattern. But I would argue this separation is not entirely necessary, since what we want is something that implements a single abstraction mapping onto a Resource which also support the primarily lifecycle methods or resource operations of GET, PUT, POST and DELETE. But there is an issue to be worked through here. These resource operations are actually class level and not object level methods. Thus if we have an abstraction to represent the resource instance, the class level methods cannot be defined in the same class except as class level (static) methods. This is a tricky problem, and I would submit the designer may make one of two choices (a) Implement the resource operations as class level methods on the Resource abstraction (ie. they will get or return the resource references as method parameters and not rely on the ‘this’ or ’self’ qualifier for getting access to the resource variables or (b) Implement the resource operations as methods on a separate one-to-one mapped class on the resource abstraction (eg. an OrderHome in case of an EJB like analogy)</p></blockquote>
<p>Again to extend the analogy of a DBMS, it argues that instead of a lot of logic being in the controllers which are the entry points of the interface (stored procedures), the interface now changes to support basic operations on the resources (tables) and that the logic could perhaps be modeled in a separate class of handler functions (triggers).</p>
<blockquote><p>Before I get into the details of this, I encourage you to take a look at my earlier post REST is the DBMS of the internet in case you have not already done so. To summarise it quickly, I have drawn the analogy that a REST based system is like a DBMS where client applications can perform direct SQL such as SELECT, INSERT, UPDATE, DELETE (GET, PUT, POST, DELETE in case of HTTP/REST) on the Tables (Resources in case of REST), and the business logic is implemented as triggers. Thus the framework will need to allow the developer to define such triggers. Such methods will need to support ability to reject the request (in case of downstream validation failures), and update the resource state (to reflect the appropriate resource state after the completion of the downstream processing). It is also feasible to imagine scenarios where such methods are triggered asynchronously. Much of the logic of the traditional controllers which controlled interactions across multiple objects etc. is likely to now be shifted into these methods. I have no particularly good name for such methods. They could be referred to as triggers, event or message handlers, glue methods, extension points etc. For the rest of this post I shall refer to these methods specifically as ‘handlers’.</p></blockquote>
</li>
<li><strong><a href="http://blog.dhananjaynene.com/2009/06/rest-soa-woa-or-roa/">ReST : SOA, WOA or ROA ?</a></strong>This post dwells on how consistent REST is with Service, Web and Resource oriented architectures. It argues that REST could perhaps be argued to be SOA only in a most specific form, and that for all practical purposes REST should not be expressed as SOA.<br />
<blockquote><p>And these constraints make the field of use so narrow, that even though REST could be argued to be a teeny weeny specific use case of SOA, it could be argued to be Service Oriented to the same extent that a Database could be argued to be Procedure Oriented (since all tables support the procedures SELECT, INSERT, UPDATE, DELETE). In other words for all practical purposes REST is not Service Oriented.</p></blockquote>
<p>It brings out some potential inconsistencies in how WOA is currently not only portrayed to be a set of architectural elements in addition to REST but also as a extension of / future of SOA.</p>
<blockquote><p>My assessment is that if WOA is a collection of Web related architecture elements in addition to REST, then the only way to successfully and consistently resolve it is by saying if WOA builds on REST then it cannot be simultaneously extending SOA.</p></blockquote>
<p>&#8230;</p>
<blockquote><p>So even if in this case there is no violation of LSP, the essential inconsistency still remains. WOA cannot be REST and SOA at the same time. This inconsistency is a bit worrying.</p></blockquote>
<p>Finally it refers to ROA as the architecture (which actually is defined with REST as the basis) with which it is most consistent with.</p>
<blockquote><p>Since ROA is a set of guidelines of an implementation of a REST architecture, I think its a slam dunk conclusion that REST is consistent with ROA (for the silly reason that ROA seems to be defined using REST <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>Per Wikipedia, Leonard Richardson and Sam Ruby further provide the guidelines for ROA in “RESTful Web Services“, but again since the evolution of ROA stems from REST, it is unsurprising that REST is consistent with ROA.</p></blockquote>
</li>
</ol>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/' rel='bookmark' title='Permanent Link: REST is the DBMS of the Internet'>REST is the DBMS of the Internet</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/' rel='bookmark' title='Permanent Link: Design Characteristics of REST / Resource Oriented Server Frameworks and Clients'>Design Characteristics of REST / Resource Oriented Server Frameworks and Clients</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/rest-soa-woa-or-roa/' rel='bookmark' title='Permanent Link: ReST : SOA, WOA or ROA ?'>ReST : SOA, WOA or ROA ?</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7vsdzANqAOo:7tvedEEOsF0: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=7vsdzANqAOo:7tvedEEOsF0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=7vsdzANqAOo:7tvedEEOsF0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7vsdzANqAOo:7tvedEEOsF0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=7vsdzANqAOo:7tvedEEOsF0:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=7vsdzANqAOo:7tvedEEOsF0: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/7vsdzANqAOo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/06/musings-on-rest/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/06/musings-on-rest/</feedburner:origLink></item>
		<item>
		<title>ReST : SOA, WOA or ROA ?</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/pkPvhWhRQDE/</link>
		<comments>http://blog.dhananjaynene.com/2009/06/rest-soa-woa-or-roa/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 19:52:35 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[rest-musings]]></category>
		<category><![CDATA[roa]]></category>
		<category><![CDATA[soa]]></category>
		<category><![CDATA[woa]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=699</guid>
		<description><![CDATA[This is part 4 of a continuing series of posts on ReST. So you might want to read up the earlier ones as well (chronologically they are the three posts before this)
Nice alphabet soup indeed. But what style of architecture does ReST (Representational State Transfer) correspond to.
Before we get into any definitional issues which are [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is part 4 of a continuing series of posts on ReST. So you might want to read up the earlier ones as well (chronologically they are the three posts before this)</em></p>
<p>Nice alphabet soup indeed. But what style of architecture does ReST (Representational State Transfer) correspond to.</p>
<p>Before we get into any definitional issues which are hugely referred to in case of such debates &#8211; I shall be referring to the currently available definitions and descriptions as available on Wikipedia viz. Service Oriented Architecture, Web Oriented Architecture and Resource Oriented Architecture.</p>
<p><strong>Service Oriented Architecture</strong></p>
<p>As per the definition on Wikipedia (emphasis is mine):</p>
<blockquote><p>In computing, service-oriented architecture (SOA) provides methods for systems development and integration where systems package functionality as interoperable services. A SOA infrastructure allows different applications to exchange data with one another.</p>
<p>Service-orientation aims at a loose coupling of services with operating systems, programming languages and other technologies that underlie applications. <em>SOA separates functions</em> into distinct units, or services, which developers make accessible over a network in order that users can combine and reuse them in the production of applications. These services communicate with each other by passing data from one service to another, or by coordinating an activity between two or more services.</p></blockquote>
<p>On the topic of Service Orientation, it further goes on to state</p>
<blockquote><p>Service-orientation is a design paradigm that specifies the <em>creation of automation logic in the form of services</em>. It is applied as a strategic goal in developing a service-oriented architecture (SOA). Like other design paradigms, service-orientation provides a means of achieving a separation of concerns.</p></blockquote>
<p>While REST does attempt to solve many similar goals as SOA, I believe there lies an important distinction. The essential focus of SOA is to separate functions or automation services. An example here is to separate an authentication service from authorisation, monitoring, logging etc. A SOA architecture that consists of a number of SOA services assembles such &#8220;<em>functionalities</em>&#8221; into one feature consistent whole. But is that how REST works ? Only in a very vague sense even if arguably so. REST standardises the functions ie. GET, PUT, POST and DELETE in case of HTTP connectors. It is arguable that REST could be used with a different set of functions, but even in that case the function set is likely to remain consistent. This is further supported by Roy Fielding&#8217;s post &#8220;<a href="http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post">It is Okay to use POST</a>&#8221; in which he argues</p>
<blockquote><p>Some people think that REST suggests not to use POST for updates.  Search my dissertation and you won’t find any mention of CRUD or POST. The only mention of PUT is in regard to HTTP’s lack of write-back caching.  The main reason for my lack of specificity is because the methods defined by HTTP are part of the Web’s architecture definition, not the REST architectural style. Specific method definitions (aside from the retrieval:resource duality of GET) simply don’t matter to the REST architectural style, so it is difficult to have a style discussion about them. <em>The only thing REST requires of methods is that they be uniformly defined for all resources (i.e., so that intermediaries don’t have to know the resource type in order to understand the meaning of the request). As long as the method is being used according to its own definition, REST doesn’t have much to say about it.</em></p></blockquote>
<p>So across the board the functions remain the same and the data types (or media types) change. Sounds familiar ? Thats like supporting SELECT, INSERT, UPDATE, DELETE on a broad range of tables each having a different schema. An argument I make in an earlier post <a href="http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/">REST is the DBMS of the Internet</a>. Moreover Roy further goes on to elaborate that in &#8220;REST intermediaries don&#8217;t have to know the resource type in order to understand the meaning of the request&#8221; and that &#8220;method is being used according to its own definition&#8221;. Each of this further introduces constraints into traditional service orientation. And these constraints make the field of use so narrow, that even though REST could be argued to be a teeny weeny specific use case of SOA, it could be argued to be Service Oriented to the same extent that a Database could be argued to be Procedure Oriented (since all tables support the procedures SELECT, INSERT, UPDATE, DELETE). In other words for all practical purposes REST is not Service Oriented.</p>
<p><strong>Web Oriented Architecture</strong></p>
<p>This is not yet a particularly widely used term yet, but I did come across a reference to it on a recent article in InfoQ &#8220;<a href="http://www.infoq.com/news/2009/06/hinchcliffe-REST-WOA">REST is a Style &#8211; WOA is the architecture</a>&#8220;. Looking it up on Wikipedia leads us to the same sources as referred to by InfoQ &#8211; articles written by Dion Hinchcliffe. Wikipedia states it as follows</p>
<blockquote><p>Web Oriented Architecture (WOA) is a style of software architecture that extends service-oriented architecture (SOA) to web based applications, and is sometimes considered to be a light-weight version of SOA. WOA is also aimed at maximizing the browser and server interactions by use of technologies such as REST and POX.</p></blockquote>
<p>But I just argued in the earlier section that REST is only a very very specific use case of SOA, whereas the statement above says WOA extends SOA to web based applications. If we were dealing with objects and not architectural styles here, an argument that X is a specific (constrained) sub type of Y and X extends Y would instantaneously be flagged off as a violation of Liskov&#8217;s Substitution Principle (LSP). So something isn&#8217;t quite right here and the whole situation does not add up to a consistent whole for me. I will leave it to the reader to decide whether there exists a flaw in my reasoning here or elsewhere. My assessment is that if WOA is a collection of Web related architecture elements in addition to REST, then the only way to successfully and consistently resolve it is by saying if WOA builds on REST then it cannot be simultaneously extending SOA.</p>
<p>To be fair I couldn&#8217;t quite find the same worlds (WOA extends SOA) in Hinchcliffe&#8217;s writings. Referring to one of them &#8220;<a href="http://hinchcliffe.org/archive/2008/02/27/16617.aspx">What is WOA ? Its the future of Service Oriented Architecture (SOA)</a>&#8220;, he refers to another of his post <a href="http://hinchcliffe.org/archive/2005/08/27/1817.aspx">&#8220;Beating a Dead Horse: What&#8217;s a SOA Again? All About Service-Orientation&#8230;&#8221;</a> which in turn states</p>
<blockquote><p>It&#8217;s here that John Reynolds&#8217; well-known SOA Elevator pitch comes tantalizingly close to capturing the essence:</p>
<blockquote><p>SOA is an architectural style that encourages the creation of loosely coupled business services. Loosely coupled services that are interoperable and technology-agnostic enable business flexibility. An SOA solution consists of a composite set of business services that realize an end-to-end business process. Each service provides an interface-based service description to support flexible and dynamically re-configurable processes.</p></blockquote>
<p>This business view is right on, and doesn&#8217;t mean business in a traditional, white-collar way. In this context, &#8220;business&#8221; means the actual functionality of the system, apart from technical details.</p></blockquote>
<p>There we go again on services. But Business Services cannot be  GET, PUT, POST, DELETE. I would emphasise again that REST does not expose business services &#8211; it exposes some very basic CRUD services. So even if in this case there is no violation of LSP, the essential inconsistency still remains. WOA cannot be REST and SOA at the same time. This inconsistency is a bit worrying. But it is likely that Hinchcliffe meant that WOA is built on REST and is similar to SOA in terms of the goals when he says WOA is the future of SOA. But honestly I could not quite figure out how exactly he would want to describe the relationship between WOA and SOA.</p>
<p><strong>Resource Oriented Architecture</strong></p>
<p>The wikipedia page states :</p>
<blockquote><p>Resource Oriented Architecture (or, ROA) is a specific set of guidelines of an implementation of the REST architecture.</p>
<p>REST, or Representational State Transfer (see Roy Thomas Fielding&#8217;s Doctoral Thesis &#8220;Architectural Styles and the Design of Network-based Software Architectures&#8221;), describes a series of architectural constraints that exemplify how the web&#8217;s design emerged. Various concrete implementations of these ideas have been created throughout time, but it has been difficult to discuss the REST architecture without blurring the lines between actual software, or the architectural principals behind them.</p></blockquote>
<p>Since ROA is a set of guidelines of an implementation of a REST architecture, I think its a slam dunk conclusion that REST is consistent with ROA (for the silly reason that ROA seems to be defined using REST <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>Per Wikipedia, Leonard Richardson and Sam Ruby further provide the <a href="http://en.wikipedia.org/wiki/Resource_Oriented_Architecture#Guidelines_for_Clarification">guidelines for ROA</a> in &#8220;<a href="http://books.google.com/books?as_isbn=0596529260">RESTful Web Services</a>&#8220;, but again since the evolution of ROA stems from REST, it is unsurprising that REST is consistent with ROA.</p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/10/service-oriented-rest-architecture-is-an-oxymoron/' rel='bookmark' title='Permanent Link: Service oriented REST architecture is an oxymoron'>Service oriented REST architecture is an oxymoron</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/musings-on-rest/' rel='bookmark' title='Permanent Link: Musings on REST'>Musings on REST</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/' rel='bookmark' title='Permanent Link: Design Characteristics of REST / Resource Oriented Server Frameworks and Clients'>Design Characteristics of REST / Resource Oriented Server Frameworks and Clients</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=pkPvhWhRQDE:mYaT28hGTzA: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=pkPvhWhRQDE:mYaT28hGTzA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=pkPvhWhRQDE:mYaT28hGTzA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=pkPvhWhRQDE:mYaT28hGTzA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=pkPvhWhRQDE:mYaT28hGTzA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=pkPvhWhRQDE:mYaT28hGTzA: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/pkPvhWhRQDE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/06/rest-soa-woa-or-roa/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/06/rest-soa-woa-or-roa/</feedburner:origLink></item>
		<item>
		<title>Design Characteristics of REST / Resource Oriented Server Frameworks and Clients</title>
		<link>http://feedproxy.google.com/~r/var/log/mind/~3/wkbKt3bDMR0/</link>
		<comments>http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 14:04:51 +0000</pubDate>
		<dc:creator>Dhananjay Nene</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[rest-musings]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[frameworks]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://blog.dhananjaynene.com/?p=690</guid>
		<description><![CDATA[This post is the third part of continuing series of articles on REST. The first one was Why REST ? and the next one was REST is the DBMS of the internet with hopefully some more to follow in the coming weeks.
Struts, Django, Ruby on Rails. We&#8217;ve worked with these and many other similar frameworks. [...]]]></description>
			<content:encoded><![CDATA[<p>This post is the third part of continuing series of articles on REST. The first one was <a href="http://blog.dhananjaynene.com/2009/06/why-rest/">Why REST ?</a> and the next one was <a href="http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/">REST is the DBMS of the internet</a> with hopefully some more to follow in the coming weeks.</p>
<p>Struts, Django, Ruby on Rails. We&#8217;ve worked with these and many other similar frameworks. Some time back I started thinking of what would a completely new ground up REST / Resource oriented framework would look like (ground up to ensure it had no legacy design to deal with). Would such frameworks be similar to the ones dominantly used today ? What about the ecosystem that surrounds and interacts with them (client libraries) ? And finally what about the implications on the fine grained object model (assuming there is one) and its relationship with the resource model ? This post deals with some of the thoughts.</p>
<p>There are some specifics the post does not address and is agnostic about :</p>
<ul>
<li>Language : I shall be avoiding language issues as much as possible. Wherever I do bring in code constructs these may be assumed to be in Java (or pseudo-Java)</li>
<li>Convention or Configuration : I think both are valid choices in their appropriate contexts, and I don&#8217;t specifically emphasise one over the other in this post</li>
</ul>
<p>The frameworks mentioned above are not the only ones out there. There are many, and some actually are very REST specific eg. Apache CXF JAX-RS or Restlet. It would certainly be interesting to contrast my thoughts with these, but for reasons of insufficiently detailed knowledge about them, I shall choose to skip it (better to not make any statements than making incorrect ones).</p>
<p>I shall be assuming a HTTP connector with GET, PUT, POST and DELETE as the constant set of operations. These four operations shall be collectively referred to as Resource Operations.</p>
<p>We shall first start with the server side characteristics, and the term <em>ROF shall refer to a Resource Oriented (server side) Framework</em></p>
<p><strong>A ROF will have a resource oriented interface : </strong>Certainly not a profound statement, but it was important to lay that down upfront. So what is a Resource Oriented Interface. Given a particular resource, a Resource Oriented Software will support or consume end points which allow you GET, PUT, POST or DELETE the resource. There is one reason why this particular constraint is relaxed just a little bit. Modern browsers do not support all the four methods easily eg DELETE and make it just slightly hard to use the PUT method. Hence these methods can also be invoked by using a URI segment containing the method name eg. delete.</p>
<p><strong>A ROF will have an abstraction to represent a resource as an end point :</strong> Again, that seems to be pretty obvious. But there is a reason why I make it explicitly. In many situations we see controllers acting as end points. To the extent a controller acts as an abstraction for a resource end point which essentially only has the resource operations as public methods, it would fit this requirement. However if I was using an Order as a resource and if I introduced an approve method on the OrderController that would not be consistent with this requirement. That would need to be modelled as an OrderApproval resource which may on successful completion, effect a state change on the Order resource to the status &#8216;approved&#8217;.</p>
<p>This is where a potential differences with conventional frameworks arise. If I was to think of it from an EJB like perspective, I would model a OrderController as a Session bean and a Order as an entity bean. In case of lightweight POJO based model, I would have an OrderController as the endpoint exposed by say using Struts and model the Order as a entity POJO and map it to the database using Hibernate. In other non java frameworks, I would have a class to represent an OrderController and another one to represent the order along ActiveRecord pattern. But I would argue this separation is not entirely necessary, since what we want is something that implements a single abstraction mapping onto a Resource which also support the primarily lifecycle methods or resource operations of GET, PUT, POST and DELETE. But there is an issue to be worked through here. These resource operations are actually class level and not object level methods. Thus if we have an abstraction to represent the resource instance, the class level methods cannot be defined in the same class except as class level (static) methods. This is a tricky problem, and I would submit the designer may make one of two choices (a) Implement the resource operations as class level methods on the Resource abstraction (ie. they will get or return the resource references as method parameters and not rely on the &#8216;this&#8217; or &#8217;self&#8217; qualifier for getting access to the resource variables or (b) Implement the resource operations as methods on a separate one-to-one mapped class on the resource abstraction (eg. an OrderHome in case of an EJB like analogy)</p>
<p><strong>Given consistent expectations of the Resource Operations these will actually be auto-magically implemented :</strong> Thats a bit of a turnaround from what I was just describing in the earlier paragraph. What I mean to suggest is that the class level methods I just referred to will be implemented within the framework. What the framework will allow are plugins to provide extended functionality at specific points. Thus a &#8220;public static Order Order.put(Order order)&#8221; method will be implicitly implemented by the framework. But before a put can be processed it needs to be validated. Thus the framework will allow the developer to plug in / override his own implementation for an Order.validate(Order order). There are multiple ways such plug-ins could be implemented. Depending upon the nature of abstraction, it could be an overridden method as I just described, or it could be a standalone method that is registered into the overall workflow (either through convention or configuration). The latter might be especially useful in case one wants to implement the functionality as stand alone methods or in case of functional programming languages. The plugin points provided could be framework specific. eg, One may want to validate a resource for consistency even at it is being read from the database. For the rest of the post I shall refer to these as plugins. In addition, framework will most certainly provide methods for for downstream handling of impact of PUT, POST or DELETE. This is covered in the next point. In case the framework  chooses to not deal with persistence, it may choose to allow capabilities for integration with other persistence frameworks.</p>
<p><strong>A ROF will provide capabilities to a developer to override or register methods to handle downstream impact of PUT, POST and DELETE : </strong> Before I get into the details of this, I encourage you to take a look at my earlier post <a href="http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/">REST is the DBMS of the internet</a> in case you have not already done so. To summarise it quickly, I have drawn the analogy that a REST based system is like a DBMS where client applications can perform direct SQL such as SELECT, INSERT, UPDATE, DELETE (GET, PUT, POST, DELETE in case of HTTP/REST) on the Tables (Resources in case of REST), and the business logic is implemented as triggers. Thus the framework will need to allow the developer to define such triggers. Such methods will need to support ability to reject the request (in case of downstream validation failures), and update the resource state (to reflect the appropriate resource state after the completion of the downstream processing).  It is also feasible to imagine scenarios where such methods are triggered asynchronously. Much of the logic of the traditional controllers which controlled interactions across multiple objects etc. is likely to now be shifted into these methods. I have no particularly good name for such methods. They could be referred to as triggers, event or message handlers, glue methods, extension points etc. For the rest of this post I shall refer to these methods specifically as &#8216;handlers&#8217;.</p>
<p>Note that the actual invocations to select, insert, update, delete the resource are *NOT* to be programmed by the developer. These are automatically handled by the framework. The developer essentially fills in the necessary logic to the plugin methods (eg. Order.validate) or handlers (eg. Order.onCreate)</p>
<p><strong>A ROF will provide a mechanism to describe or map a resource abstraction to to the actual programming constructs :</strong> There are a number of ways this could be achieved. XML, YAML, DSL, Annotation &#8211; take your pick. Also the actual class could be defined (as in case of a POJO) and the resource characteristics mapped onto it, or the class may manifest itself at runtime based on metaprogramming around the metadata. Sample possibilities here are Hibernate like Resource-to-Object-to-Relation mapping (using either Annotations or XML) or a a completely metaprogrammed ActiveResource. One important aspect that the framework will need to cover is the situations where a Resource is a composite of many or partial underlying business objects. eg. an Order resource instance could theoretically span one Order instance and many OrderItem instances. Thus a one to one relationship between a resource and underlying business objects (or datastructures) is not assumed. What is assumed is that the framework will allow such relationships to be described or introspected.</p>
<p><strong>A ROF will allow resources to be mapped onto URI or URI segments : </strong> This is too obvious an requirement to be explained and is mentioned here only for completeness.</p>
<p><strong>A ROF will allow foreign keys across resources which manifest themselves as URIs to be mapped onto the underlying business object references : </strong> Resources refer to each other through URIs. The underlying business objects refer to each other through object references. Given the resource descriptions and URI mappings, the framework should allow for a transparent referencing/dereferencing between such URIs and the object references.</p>
<p><strong>A ROF will allow factory methods for locating or allow injection of other resources / business objects :</strong> Within the handler functions, developers will need references to the associated resources or business objects. I say resources or business objects, since the developer may choose to interact with these at a coarse grained (resource) or fine grained (business object) level. The framework should allow the necessary support for such activities.</p>
<p><strong>A ROF may provide additional support for typical aspects of lifecycle (eg. validation) :</strong> While I mentioned validate as a possible plugin function. However given the omnipresence of validations, the framework may provide additional support for such activities. Thus the framework may choose to automatically implement such capabilities using the resource descriptions.</p>
<p><strong>A ROF may provide capabilities for domain specific extension of resource capabilities : </strong> Certain domains have standardised mechanisms of working with resources. As an example most banking systems based on the four eyes principle require approval activities. While this particular aspect is much tougher than it seems, a ROF may choose to allow extension of such capabilities using template like functions or mix ins. As an example in this situation, once an Order resource is defined, an OrderApproval resource will be automatically made available as will the GET and PUT methods on it (POST and DELETE in this particular case may not be relevant), as will the necessary and appropriate handler functions on OrderApproval.</p>
<p><strong>A ROF will provide capabilities for automatically generating the resource representation from the resource and vice-versa : </strong> Resources manifest themselves in multiple possible formats eg. XML, JSON etc. An ROF will allow such transformations between the representation and the resource/business object instance automatically.</p>
<p><strong>A ROF will provide capabilities for assembling more complex representations using templates :</strong> In many situations, especially when the representations are being composed for manual (browser based) consumption, additional resources may need to be pulled into a view. A ROF will allow for such assembly of resources to be composed into a final view using templates.</p>
<p><strong>A ROF will allow for introduction of appropriate additional URIs in views using templates : </strong> Thanks to HATEOAS (I&#8217;ve really avoided it thus far <img src='http://blog.dhananjaynene.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ), the framework will need to allow some mechanism of describing what are the additional context specific URIs to be included in the final representation. The template logic should allow the developer to specify such URIs.</p>
<p><strong>A ROF should allow for the resource / media-type descriptions to be shipped in band with the resource representation :</strong> Since REST allows media types to be auto discovered and auto described, the framework should allow for the metadata for such media types to be also presented to the client. While I think it is essential that such in band information should be conveyed on demand, the framework may also optionally support upfront interrogation for media types and their details, which will require such information to be shipped out of band as well. I am not aware of any specific standards around such interrogation APIs so the framework could implement a custom API for the same. The actual metadata could be represented using any of the typical appropriate standards such as RDFa, XML Schema snippets etc.</p>
<p><strong>A ROF should optionally allow support for auto generation of bindings for clients :</strong> I really really cringe as I write this. I cringe because to me the great attraction of REST is the simplicity and the ease of introducing incremental integration. The client binding generation (especially if it is statically generated) flies in the face of many accepted lightweight design scenarios. However I think there are likely to be some situation where availability of such client side bindings would be helpful. When possible (eg. with dynamically typed, metaprogramming capable languages like Python or Ruby), such bindings should be dynamic. In such cases the client can automatically introspect the server side media types and make available the necessary client side objects on the fly. In cases where statically typed languages such as Java or Scala are used, the client side may choose to expose everything as generic datastructures (e.g trees of name value pairs) or may allow for generation and compilation of client side bindings. I have no specific thoughts around the API support needed on the client side, except that quite obviously this would include support for the resource construction, resource operations etc. and that they would allow the client to interact with the server using the underlying language constructs rather having to work at a raw HTTP level.</p>
<p>In addition to the characteristics described above, I suspect frameworks will have many other optional characteristics such as support for monitoring, auditing / logging, transaction management, object pooling etc. etc. However these are unlikely to be particularly interesting when focusing on the framework aspects especially from a resource oriented perspective, which is indeed the focus of this post.</p>
<p><strong><em>Update : </em></strong> InfoQ covered this blog post here : <a href="http://www.infoq.com/news/2009/06/designing-rest-frameworks">Design Characteristics Of Resource Oriented Server Frameworks</a></p>


<p>Related posts:<ol><li><a href='http://blog.dhananjaynene.com/2009/06/musings-on-rest/' rel='bookmark' title='Permanent Link: Musings on REST'>Musings on REST</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/why-rest/' rel='bookmark' title='Permanent Link: Why REST ?'>Why REST ?</a></li>
<li><a href='http://blog.dhananjaynene.com/2009/06/rest-is-the-dbms-of-the-internet/' rel='bookmark' title='Permanent Link: REST is the DBMS of the Internet'>REST is the DBMS of the Internet</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/var/log/mind?a=wkbKt3bDMR0:OMwb0aPLKBk: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=wkbKt3bDMR0:OMwb0aPLKBk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=wkbKt3bDMR0:OMwb0aPLKBk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=wkbKt3bDMR0:OMwb0aPLKBk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/var/log/mind?i=wkbKt3bDMR0:OMwb0aPLKBk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/var/log/mind?a=wkbKt3bDMR0:OMwb0aPLKBk: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/wkbKt3bDMR0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.dhananjaynene.com/2009/06/design-characteristics-of-rest-resource-oriented-server-frameworks-and-clients/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 9.664 seconds -->
