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

<channel>
	<title>Dan Weinreb's blog &#187; Software Engineering</title>
	<atom:link href="http://danweinreb.org/blog/category/software-engineering/feed" rel="self" type="application/rss+xml" />
	<link>http://danweinreb.org/blog</link>
	<description>Software and Innovation</description>
	<lastBuildDate>Mon, 05 Sep 2011 20:12:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>What Does the Proof of the &#8220;CAP theorem&#8221; Mean?</title>
		<link>http://danweinreb.org/blog/what-does-the-proof-of-the-cap-theorem-mean</link>
		<comments>http://danweinreb.org/blog/what-does-the-proof-of-the-cap-theorem-mean#comments</comments>
		<pubDate>Mon, 12 Jul 2010 13:23:15 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://danweinreb.org/blog/?p=357</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelSeveral years back, Eric Brewer of U.C. Berkeley presented the &#8220;CAP conjecture&#8221;, which he explained in these slides from his keynote speech at the PODC conference in 2004. The conjecture says that a system cannot be consistent, available, and partition-tolerant; that is, it can have two of these properties, but not all three. [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fwhat-does-the-proof-of-the-cap-theorem-mean&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/what-does-the-proof-of-the-cap-theorem-mean" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>Several years back, Eric Brewer of U.C. Berkeley presented the &#8220;CAP conjecture&#8221;, which he explained in <a href="http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf"> these slides from his keynote speech at the PODC conference in 2004</a>.  The conjecture says that a system cannot be consistent, available, and partition-tolerant; that is, it can have two of these properties, but not all three.  This idea has been very influential.</p>
<p>Seth Gilbert and Nancy Lynch, of MIT, in 2002, wrote a now-famous<a href="http://people.csail.mit.edu/sethg/pubs/BrewersConjecture-SigAct.pdf"> paper called &#8220;Brewer&#8217;s Conjecture and the Feasibility of Consistent Available Partition-Tolerant Web Services&#8221;</a>.  It is widely said that this paper <em>proves</em> the conjecture, which is now considered a theorem.  Gilbert and Lynch clearly proved <em>something</em>, but what does the proof mean by &#8220;consistency&#8221;, &#8220;availability&#8221;, and &#8220;partition-tolerance&#8221;?</p>
<p>Many people refer to the proof, but not all of them have actually read the paper, thinking that it&#8217;s all obvious.  I wasn&#8217;t so sure, and wanted to get to the bottom of it.  There&#8217;s something about my personality that drives me to look at things all the way down to the details before I feel I understand. (This is not always a good thing: I sometimes lose track of what I originally intended to do, as I &#8220;dive down a rat-hole&#8221;, wasting time.)  For at least a year, I have wanted to really figure this out.</p>
<p>A week ago, I came across <a href="http://pl.atyp.us/wordpress/?p=2521/"> a blog entry called &#8220;Availability and Partition Tolerance&#8221;</a> by <a href="http://pl.atyp.us/wordpress/?page_id=1278">Jeff Darcy</a>. You can&#8217;t imagine how happy I was to find someone who agreed that there is confusion about the terms, and that they need to be clarified. Reading Jeff&#8217;s post inspired me to finally read Gilbert and Lynch&#8217;s paper carefully and write these comments.</p>
<p>I had an extensive email conversation with Jeff, without whose help I could not have written this.  I am very grateful for his generous assistance.  I also thank Seth Gilbert for helping to clarify his paper for me.  I am solely responsible for all mistakes.</p>
<p>I will now <a href="http://en.wikipedia.org/wiki/Sister_Mary_Ignatius_Explains_It_All_For_You"> explain it all for you</a>.  First I&#8217;ll lay out the basic concepts and terminology.  Then I&#8217;ll discuss what &#8220;C&#8221;, &#8220;A&#8221;, and &#8220;P&#8221; mean, and the &#8220;CAP theorem&#8221;.  Next I&#8217;ll discuss &#8220;weak consistency&#8221;, and summarize the meaning of the proof for practical purposes.</p>
<h4>Basic Concepts</h4>
<p>The paper has terminology and axioms that must be laid out before the proof can be presented.</p>
<p>A distributed system is built of &#8220;nodes&#8221; (computers), which can (attempt to) send messages to each other over a network.  But the network is not entirely reliable.  There is no bound on how long a message might take to arrive.  This implies that a message might &#8220;get lost&#8221;, which is effectively the same as taking an extremely long time to arrive.  If a node sends a message (and does not see an acknowledgment), it has no way to know whether the message was received and processed or not, because either the request or the response might have been lost.</p>
<p>There are &#8220;objects&#8221;, which are abstract resources that reside on nodes.  Objects can perform &#8220;operations&#8221; on other objects.  Operations are synchronous: some thread issues a request and expects a response.  Operations do not request other operations, so they do not do any messaging themselves.</p>
<p>There can be replicas of an object on more than one node, but for the most part that doesn&#8217;t affect the following discussion.  An operation could &#8220;read X and return the value&#8221;, &#8220;write X&#8221;, &#8220;add X to the beginning of a queue&#8221;, etc.  I&#8217;ll just say &#8220;read&#8221; for an operation that has no side-effects and returns some part of the state of the object, and &#8220;write&#8221; to mean an operation that performs side-effects.</p>
<p>A &#8220;client&#8221; is a thread running on some node, which can &#8220;request&#8221; an object (on any node) to perform an operation. The request is sent in a message, and the sender expects a response message, which might returns a value, and which confirms that the operation was performed.  In general, more than one thread could be performing operations on one object.  That is, there can be <em>concurrent</em> requests.</p>
<p>The paper says: &#8220;In this note we will not consider stopping failures, though in some cases a stopping failure can be modeled as a node existing in its own unique component of a partition.&#8221;  Of course in any real distributed system, nodes can crash.  But for purposes of this paper, a crash is considered to be a network failure, because from the point of view of another node, there&#8217;s no way to distinguish between the two.  A crashed node behaves exactly like a node that&#8217;s off the network.</p>
<p>You might say that if a node goes off the network and comes back, that&#8217;s not the same as a crash because the node loses its volatile state. However, this paper does not concern itself with a distinction between volatile and durable memory.  There&#8217;s no problem with that; issues of what is &#8220;in RAM&#8221; versus &#8220;on disk&#8221; are orthogonal to what this paper is about.</p>
<h4>Consistent</h4>
<p>The paper says that consistency &#8220;is equivalent to requiring requests of the distributed shared memory to act as if they were executing on a single node, responding to operations one at a time.&#8221; They explain this more explicitly by saying that consistency is equivalent to requiring all operations (in the whole distributed system) to be &#8220;linearizable&#8221;.</p>
<p>&#8220;Linearizability&#8221; is a formal criterion presented in the paper &#8220;Linearizability: A Correctness Condition for Concurrent Objects&#8221;, by Maurice Herlihy and Jeannette Wing.  It means (basically) that operations behave <em>as if</em> there were no concurrency.</p>
<p>The linearizability concept is based a model in which there is a set of threads, each of which can send an operation to an object, and later receive a response.  Despite the fact that the operations from the different threads can overlap in time in various ways, the responses are <em>as if</em> each operation took place instantaneously, in some order.  The order must be consistent with each thread&#8217;s own order, so that a read operation in a thread always sees the results of that thread&#8217;s own writes.</p>
<p>Linearizability <em>per se</em> does not include failure atomicity, which is the &#8220;A&#8221; (&#8220;atomic&#8221;) in &#8220;ACID&#8221;.  But Gilbert and Lynch assume no node failures. So operations are atomic: they always run to completion, even if their response messages get lost.</p>
<p>So by &#8220;consistent&#8221; (&#8220;C&#8221;), the paper means that every object is linearizable.  (That&#8217;s not what the &#8220;C&#8221; in &#8220;ACID&#8221; means, by the way, but that&#8217;s not important.)  Very loosely, &#8220;consistent&#8221; means that if you get a response, it has the right answer, despite concurrency.</p>
<p>This is <em>not</em> what the &#8220;C&#8221; in &#8220;ACID transaction&#8221; means.  It&#8217;s what the &#8220;I&#8221; means, namely &#8220;isolation&#8221; from concurrent operations.  This is probably a source of confusion sometimes.</p>
<p>Furthermore, the paper says nothing about transactions, which have would have a beginning, a <em>sequence</em> of operations, and an end, which may commit or abort.  &#8220;ACID&#8221; is talking about the entire transaction.  The &#8220;linearizability&#8221; criterion only talks about individual operations on objects.  (So the whole &#8220;ACID versus BASE&#8221; business, while cute, can be misleading.)</p>
<h4>Available</h4>
<p>&#8220;Available&#8221; is defined as &#8220;every request received by a non-failing node in the system must result in a response.&#8221;  The phrase &#8220;non-failing node&#8221; seemed to imply that some nodes might be failing and others not.  But since the paper postulates that nodes never fail, I believe the phrase is redundant, and can be ignored. After the definition, the paper says &#8220;That is, any algorithm used by the service must eventually terminate.&#8221;</p>
<p>The problem here is that &#8220;eventually&#8221; could mean a trillion years. This definition of &#8220;available&#8221; is only useful if it includes some kind of real-time limit: the response must arrive within a period of time, which I&#8217;ll call the maximum latency.</p>
<p>Next, it&#8217;s very important to notice that &#8220;A&#8221; says nothing about the content of the response.  It could be anything, as far as &#8220;A&#8221; is concerned; it need not be &#8220;successful&#8221; or &#8220;correct&#8221;.  (If think otherwise, see section 3.2.3.)</p>
<p>So &#8220;available&#8221; (&#8220;A&#8221;) means: If a client sends a request to a node, it always gets back some response within L time, but there is no guarantee about contents of the response.</p>
<h4>Partition Tolerant</h4>
<p>There is no definition, <em>per se</em>, of the term &#8220;partition-tolerant&#8221;, not even in section 2.3, &#8220;Partition Tolerance&#8221;.</p>
<p>First, what is a &#8220;partition&#8221;? They first define it to mean that there is a way to assort all the nodes into separate sets, which they call &#8220;components&#8221;, and all messages sent from a node in one component to another nodes in a separate component are lost. But then they go on to say &#8220;And any pattern of message loss can be modeled as a temporary partition separating the communicating nodes at the exact instance the message is lost.&#8221; or their formal purposes, &#8220;partition&#8221; simply means that a message can be lost. (The whole &#8220;component&#8221; business can be disregarded.)  That&#8217;s probably <em>not</em> what you had in mind!</p>
<p>In real life, some messages are lost and some aren&#8217;t, and it&#8217;s not exactly clear when a &#8220;partition&#8221; situation starts, is happening, or ends.  I realize that for practical purposes, we usually know what a partition means, but if we&#8217;re going to do formal proofs and understand what was proved, one must be completely clear about these terms.</p>
<p>Even in a local-area network, packets can be dropped.  Protocols like TCP re-transmit packets until the destination acknowledges that they have arrived.  If that happens, it&#8217;s clearly not a network failure from the point of view of the application.  &#8220;Losing messages&#8221; must have something to do with nodes entirely unable to communicate for a &#8220;long&#8221; time compared to the latency requirements of the system.</p>
<p>Furthermore, remember that node failure is treated as a network failure.</p>
<p>So &#8220;partition-tolerant&#8221; (&#8220;P&#8221;) means that any guarantee of consistency or availability is still guaranteed even if there is a partition.  In other words, if a system is <em>not</em> partition-tolerant, that means that <em>if</em> the network can lose messages or any nodes can fail, <em>then</em> any guarantee of atomicity or consistency is voided.</p>
<h4>CAP</h4>
<p>The CAP theorem says that a distributed system as described above cannot have properties C, A, and P all at the same time.  You can only have two of them.  There are three cases:</p>
<p>AP: You are guaranteed get back responses promptly (even with network partitions), but you aren&#8217;t guaranteed anything about the value/contents of the response.  (See section 3.2.3.) A system like this is entirely useless, since any answer can be wrong.</p>
<p>CP: You are guaranteed that any response you get (even with network partitions) has a consistent (linearizable) result.  But you might not get any responses whatsoever.  (See section 3.2.1.)  This guarantee is also completely useless, since the entire system might always behave as if it were totally down.</p>
<p>CA: If the network never fails (and nodes never crash, as they postulated earlier), then, unsurprisingly, life is good.  But if messages could be dropped, <em>all</em> guarantees are off.  So a CA guarantee is only useful in a totally reliable system.</p>
<p>At first, this seems to mean that practical, large distributed systems (which aren&#8217;t entirely reliable) can&#8217;t make <em>any</em> useful guarantees!  What&#8217;s going on here?</p>
<h4>Weak Consistency</h4>
<p>Large-scale distributed systems that must be highly available can provide some kind of &#8220;weaker&#8221; consistency guarantee than linearizability.  Most such systems provide what they call &#8220;eventual consistency&#8221; and may return &#8220;stale data&#8221;.</p>
<p>For some applications, that&#8217;s OK.  Google search is an obvious case: the search is already specified/known to be using &#8220;stale&#8221; data (data since the last time Google looked at the web page), so as long as partitions are fixed quickly relative to the speed of Google&#8217;s updating everything, (and even if sometimes not, for that matter), nobody is going to complain.</p>
<p>Just saying that results &#8220;might be stale&#8221; and will be &#8220;eventually consistent&#8221; is unfortunately vague.  How stale can it be, and how long is &#8220;eventually&#8221;? If there&#8217;s no limit, then there&#8217;s no useful guarantee.</p>
<p>For a staleness-type weak consistency guarantee, you&#8217;d like to be able to say something like: &#8220;operations (that read) will always return a result that was consistent with all the other operations (that write) no longer ago than time X&#8221;.  And this implies that &#8220;write&#8221; operations are never lost, i.e. always happen within a fixed time bound.</p>
<p><strong>t-Connected Consistency</strong></p>
<p>Gilbert and Lynch discuss &#8220;weakened consistency&#8221; in section 4. It&#8217;s also about stale data, but with &#8220;formal requirements on the quality of stale data returned&#8221;.  They call it &#8220;t-Connected Consistency&#8221;.</p>
<p>It makes two assumptions.  (a) Every node has a clock that can be used to do timeouts. The clocks don&#8217;t have to be synchronous with each other.  (b) There&#8217;s some time period after which you can assume that an unanswered message must be lost. (c) Every node processes a received message within a given, known time.</p>
<p>The real definition of &#8220;t-Connected Consistency&#8221; is too formal for me to explain here (see section 4.4).  It (basically) guarantees (1) when there is no partition, the system is fully consistent; (2) if a partition happens, requests can see stale data; and (3) and after the partition is fixed, there&#8217;s a time limit on how long it takes for consistency to return.</p>
<p>Are the assumptions OK in practice?  Every real computer can do timeouts, so (a) is no problem.  You can always ignore any responses to messages after the time period, so (b) is OK.  It&#8217;s not obvious that every system will obey (c), but some will.</p>
<p>I have two reservations.  First, if the network is so big that it&#8217;s never entirely working at any one time, what would guarantee (3) mean?  Second, in the algorithm in section 4.4, in the second step (&#8220;<em>write</em> at node A&#8221;), it retries as long as necessary to get a response.  But that could exceed L, violating the availability guarantee.</p>
<p>So it&#8217;s not clear how attractive t-Connected Consistency really is.  It can be hard it is to come up with formal proofs of more complicated, weakened consistency guarantees.  Most working software engineers don&#8217;t think much about formal proofs, but don&#8217;t underrate them.  Sometimes they can help you identifying bugs that would otherwise be hard to track down, before they happen.</p>
<p>Jeff Darcy wrote <a href="http://pl.atyp.us/wordpress/?p=2532">a blog posting about &#8220;eventual consistency&#8221;</a> about a half year ago, which I recommend.  And there are other kinds of weak consistency guarantees, such as the one provided by <a href="http://s3.amazonaws.com/AllThingsDistributed/sosp/amazon-dynamo-sosp2007.pdf"> Amazon&#8217;s Dynamo key-store</a>, which worth examining.</p>
<h4>Reliable Networks</h4>
<p>Can&#8217;t you just make the network reliable, so that messages are never lost?  (&#8220;Never&#8221; meaning that the probability of losing a message is as low as other failure mode that you&#8217;re not protecting against.)</p>
<p>Lots and lots of experience has shown that in a network with lots of routers and such, no matter how much redundancy you add, you <em>will</em> experience lost messages, and you <em>will</em> see partitions that last for a significant amount of time.  I don&#8217;t have a citation to prove this, but, ask around and that&#8217;s what experienced operators of distributed systems will always tell you.</p>
<p>How many routers is &#8220;lots&#8221;?  How reliable is it if you have no routers (layer 3 switches), only hubs (layer 2 switches)?  What if you don&#8217;t even have hubs?  I don&#8217;t have answers to all this.  But if you&#8217;re going to build a distributed system that depends on a reliable network, you had better ask experienced people about these questions.  If it involves thousands of nodes and/or is geographically distributed, you can be sure that the network will have failures.</p>
<p>And again, as far as the proof of the CAP theorem is concerned, node failure is treated as a network failure.  Having a perfect network does you no good if machines can crash, so you&#8217;d also need each node to be highly-available in and of itself.  That would cost a lot more than using &#8220;commercial off-the-shelf&#8221; computers.</p>
<h4>The Bottom Line</h4>
<p>My conclusion is that the proof of the CAP theorem means, in practice: if you want to build a distributed system that is (1) large enough that nodes can fail and the network can&#8217;t be guaranteed to never lose messages, <em>and</em> (2) you want to get a useful response to every request within a specified maximum latency, <em>then</em> the best you can guarantee about the meaning of the response is that it is guaranteed to have some kind of &#8220;weak consistency&#8221;, which you had better carefully <em>define</em> in such a way that it&#8217;s useful.</p>
<h4>P.S.</h4>
<p>After writing this but just before posting it, Alex Feinberg added a comment to my previous blog post with a link to <a href="http://www.cloudera.com/blog/2010/04/cap-confusion-problems-with-partition-tolerance/">this excellent post by Henry Robinson</a>, which discusses many of the same issues and links to even more posts.  If you want to read more about all this, take a look.</p>
<p><img id="smallDivTip" style="border: 0px solid blue; z-index: 90; opacity: 1; position: absolute; left: 634px; top: 520px;" src="chrome://dictionarytip/skin/dtipIconHover.png" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/what-does-the-proof-of-the-cap-theorem-mean/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>How to be a Programmer</title>
		<link>http://danweinreb.org/blog/how-to-be-a-programmer</link>
		<comments>http://danweinreb.org/blog/how-to-be-a-programmer#comments</comments>
		<pubDate>Sat, 10 Jul 2010 22:34:12 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Book]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://danweinreb.org/blog/?p=336</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelIf you are, or want to be, a programmer, you should read &#8220;How to be a Programmer: A Short, Comprehensive, and Personal Summary&#8221; by Robert L. Read. You can read it free, as PDF or HTML, or buy it as a paperback book for around $12. It&#8217;s 41 pages long (plus appendixes including [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fhow-to-be-a-programmer&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/how-to-be-a-programmer" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>If you are, or want to be, a programmer, you should read &#8220;How to be a Programmer: A Short, Comprehensive, and Personal Summary&#8221; by Robert L. Read.  <a href="http://samizdat.mines.edu/howto/">You can read it free, as PDF or HTML</a>, or <a href="http://www.amazon.com/How-Be-Programmer-Comprehensive-Personal/dp/1440439176/ref=sr_1_2?s=books&amp;ie=UTF8&amp;qid=1278788259&amp;sr=1-2">buy it as a paperback book for around $12.</a></p>
<p>It&#8217;s 41 pages long (plus appendixes including the GPL), so it&#8217;s not all that short.  But it&#8217;s concise, simple, direct, and packed with extremely useful information that you won&#8217;t find anywhere else.</p>
<p>It includes some excellent advice about programming itself, but much more than just how to write code.  For example:</p>
<ul>
<li> How to Deal with Intermittent Bugs</li>
<li> How to Work with Poor Code</li>
<li> How to Deal with Difficult People</li>
<li> How to Stay Motivated</li>
<li> How to Disagree Honestly and Get Away with It</li>
<li> How to Know When to Apply Fancy Computer Science</li>
<li> How to Handle Boring Tasks</li>
<li> How to Gather Support for a Project</li>
<li> How To Tell People Things They Don&#8217;t Want to Hear</li>
</ul>
<p>Based on my own experience, everything he says hits the nail right on the head.  I do not have a single major disagreement with anything he says.  (I have a few quibbles, and a very few points are dated, as it was written in 2003.)</p>
<p>Here are a few pieces of advice, so you can see what kind of thing he talks about:</p>
<ul>
<li>When debugging, you may see things nearby that need improvement, but don&#8217;t fix those at the same time.  (I make this mistake often; it&#8217;s just so tempting.)</li>
<li>If your system has redundant components so that if degrades gracefully, it&#8217;s especially important to have monitors that let you know that this is going on.</li>
<li>The way you interview a programmer will affect how much he or she wants to work for your company.</li>
<li>At the end of doing a job interview, sell your company.  But you are talking to a programmer, so don&#8217;t color the truth.  Start off with the bad stuff, then finish strong with the good stuff.</li>
</ul>
<p>Everyone has missed deadlines because they neglected to include all the factors that contribute to the time it takes to complete a task.  Here&#8217;s a checklist compiled from various sections of the essay, that you might want to use:</p>
<ul>
<li>Documentation</li>
<li>Unit testing</li>
<li>Integration testing</li>
<li>Demos</li>
<li>Planning itself</li>
<li>Internal team meetings</li>
<li>Communicating with other groups</li>
<li>Dealing with outsiders</li>
<li>Vacation time</li>
<li>Sick time</li>
<li>Mandatory company-wide training seminar</li>
<li>Scheduled periodic activities</li>
<li>Maintenance of existing products</li>
<li>Maintenance of the development environment</li>
<li>Some failure</li>
<li>What part will each which individual work on</li>
<li>Problems that cannot presently even be conceptualized</li>
</ul>
<p>Make the time in your schedule to read this!</p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/how-to-be-a-programmer/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Coders At Work, by Peter Seibel</title>
		<link>http://danweinreb.org/blog/coders-at-work-by-peter-seibel</link>
		<comments>http://danweinreb.org/blog/coders-at-work-by-peter-seibel#comments</comments>
		<pubDate>Sun, 15 Nov 2009 18:40:13 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Book]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://danweinreb.org/blog/?p=245</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelIn his new book, Coders at Work, Peter Seibel interviews some of the best software developers in the world, asking how they work, what practices they follow, how they learned, and what advice they can offer. Because Peter is, himself, an experienced senior software developer, he knows most relevant questions to ask, the [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fcoders-at-work-by-peter-seibel&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/coders-at-work-by-peter-seibel" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>In his new book, <a href="http://www.codersatwork.com/">Coders at Work</a>, Peter Seibel interviews some of the best software developers in the world, asking how they work, what practices they follow, how they learned, and what advice they can offer.  Because Peter is, himself, an experienced senior software developer, he knows most relevant questions to ask, the ones that have to do with how real programmers do their work.  He engages in a real back-and-forth conversation rather than just presenting a questionairre.  You feel like you&#8217;re sitting there with them, as he asks all the same questions you&#8217;d want to ask if you were there yourself.</p>
<p>How do you you find the best programmers?  He ran his own little contest: he got a lot of nominations, and people voted.  I am confident that this worked, because a lot of the people he interviewed are people I know to be among the best.  I know Guy L. Steele Jr and L Peter Deutsch, and consider them two of the very best in the world.  Most of the others I have heard of.</p>
<p>Peter is also the author of <a href="http://www.amazon.com/Practical-Common-Lisp-Peter-Seibel/dp/1590592395/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1257110992&#038;sr=8-1">Practical Common Lisp</a>, the best book to read if you want to write real programs in Common Lisp.  His understanding of the language and its deep concepts are second to none.  He has also done advanced software development at several companies, including BEA Systems and Kenamea.  Having that kind of experience lets him ask probing and relevant questions that reveal what&#8217;s really interesting about how the interviewees work and think.  There&#8217;s no other book like it.</p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/coders-at-work-by-peter-seibel/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Programming with Concurrency</title>
		<link>http://danweinreb.org/blog/programming-with-concurrency</link>
		<comments>http://danweinreb.org/blog/programming-with-concurrency#comments</comments>
		<pubDate>Mon, 27 Jul 2009 13:26:30 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Europe]]></category>
		<category><![CDATA[Guy L. Steele Jr.]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://danweinreb.org/blog/?p=184</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelNew high-speed computers will have more and more cores as the years go by, and the ramp-up has started and is going very quickly.  To take advantage of those processors, some programs will need to use interesting (complicated and novel) concurrency. But the history of concurrent software is littered with approaches that just [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fprogramming-with-concurrency&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/programming-with-concurrency" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>New high-speed computers will have more and more cores as the years go by, and the ramp-up has started and is going very quickly.  To take advantage of those processors, some programs will need to use interesting (complicated and novel) concurrency.</p>
<p>But the history of concurrent software is littered with approaches that just turned out to be too hard to use, and the software was slow to develop and very hard to debug.  Now that we&#8217;re all in the same boat, how do we solve the software problem?</p>
<p>Many language designers think that the answer lies in pure (side-effect free) programming.  The best known, and quite practical, languages that are pure are Haskell and Erlang.</p>
<p>But many new languages are arriving based on the idea that you should use mostly side-effect-free code, and then when side-effects are needed, use transactions.  This is at least a trend if not a movement or revolution.</p>
<p>When Guy Steele came back from the <a href="http://jaoo.dk/aarhus-2008/conference/" target="_blank">JAOO Conference</a>, I asked him for a quick report, and he sent me this (very slightly copy edited, used with Guy&#8217;s permission):</p>
<blockquote><p>I was stunned by the end of the first day of JAOO 2008 when I realized that Anders Hejlsberg had given a plenary talk on C#, I had given a talk on Fortress, Bill Venners had given a talk on Scala, and Erik Meijer had given a talk on functional programming, and we had all delivered approximately the same message to this object-oriented crowd: the multicores are coming—no, they&#8217;re <em>here</em>—and the only plausible way to deal with them in the long run is to rein in the side effects inherent to the OO point of view and move as much as possible to a functional programming style with mostly-immutable data structures and implicit parallelism.</p></blockquote>
<p>I am very excited by the new Clojure language, which is a dialect of Lisp based on exactly these same principles.  Rich Hickey apparently wasn&#8217;t at JAOO, but would have found friends there!</p>
<p>Normally I don&#8217;t try to learn a language unless I&#8217;m about to actually program in it.  But it&#8217;s worth learning a language when you pick up fundamental new ideas that might be helpful (or just interesting).  Haskell is like that (thanks, Alan Bawden, for letting me know).</p>
<p>If you might have to write highly-concurrent programs in the future, I recommend that you keep your eyes on all this.</p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/programming-with-concurrency/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Why Did M.I.T. Switch from Scheme to Python?</title>
		<link>http://danweinreb.org/blog/why-did-mit-switch-from-scheme-to-python</link>
		<comments>http://danweinreb.org/blog/why-did-mit-switch-from-scheme-to-python#comments</comments>
		<pubDate>Sun, 10 May 2009 13:30:15 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Education]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://danweinreb.org/blog/?p=148</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelI&#8217;ve been seeing mail and blog postings, particularly from people in the Lisp community, why MIT has switched from using Scheme to Python in the freshman core curriculum for the department of Electrical Engineering and Computer Science. At the International Lisp Conference, Prof. Gerry Sussman gave a short impromptu talk explaining the new [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fwhy-did-mit-switch-from-scheme-to-python&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/why-did-mit-switch-from-scheme-to-python" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>I&#8217;ve been seeing mail and blog postings, particularly from people in the Lisp community, why MIT has switched from using Scheme to Python in the freshman core curriculum for the department of Electrical Engineering and Computer Science.</p>
<p>At the <a href="http://www.international-lisp-conference.org/2009/index" target="_blank">International Lisp Conference</a>, <a href="http://en.wikipedia.org/wiki/Gerald_Jay_Sussman" target="_blank">Prof. Gerry Sussman</a> gave a short impromptu talk explaining the <a href="http://www.eecs.mit.edu/ug/newcurriculum/index.html" target="_blank">new freshman curriculum</a>.  Just to get a second opinion, I later called <a href=" http://eecsfacweb.mit.edu/facpages/white.html" target="_blank">Prof. Jacob White</a>, one of the designers of the curriculum and lecturers for the core courses.  (Digression: Jacob and I have been close friends since I was six years old!)  He confirmed Gerry&#8217;s description.</p>
<p>Asking why they changed languages is, in some sense, the wrong question.</p>
<p>The freshman software engineering course, since 1985, has been based on the book <a href="http://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs">Structure and Interpretation of Computer Programs</a> (<a href="http://mitpress.mit.edu/sicp/">known as SICP</a>), which uses Scheme.  The course is now nearly thirty years old.  Engineering has changed quite a lot in thirty years.  Since 1995, Gerry and his co-author <a href="http://en.wikipedia.org/wiki/Hal_Abelson" target="_blank">Prof. Hal Abelson</a> have advocated changing the freshman curriculum radically, not basing it on SICP.</p>
<p>In 1980, computer engineering was based on starting with clearly-defined things (primitives or small programs) and using them to build larger things that ended up being clearly-defined.  Composition of these fragments was the name of the game.</p>
<p>However, nowadays, a real engineer is given a big software library, with a 300-page manual that&#8217;s full of errors.  He&#8217;s also given a robot, whose exact behavior is extremely hard to characterize (what happens when a wheel slips?). The engineer must learn to perform scientific experiments to find out how the software and hardware actually work, at least enough to accomplish the job at hand.  Gerry pointed out that we may not like it this way (&#8220;because we&#8217;re old fogies&#8221;), but that&#8217;s the way it is, and M.I.T. has to take that into account.</p>
<p>The new approach also has the big advantage that it combines computer science with electrical engineering, whereas the old one taught them as entirely separate disciplines.  This way, students see how they interrelate.  Also, as Jacob points out, some of the same macro-principles apply to both software and hardware, and the students see this illustrated.  There is extensive lab work, making robots and mobile applications.</p>
<p>It just so happens that the robotics substrate software that comes with the system they&#8217;re using is programmed in Python.  Similarly, the mobile software environment is based on Python.  (Or, at least, the original plan was to use such a substrate, although it may have changed for various business reasons.)</p>
<p>Changing programming languages was absolutely not a goal of the curriculum change.  It was merely the result of the consequences of various decisions.  We can always discuss how it came to be that the robots and mobile devices are using Python instead of some other language, but that&#8217;s not the question being addressed here.  M.I.T. has nothing against Scheme. (And, of course, M.I.T. does teach classic software engineering, later in the curriculum.)</p>
<p>(<a href="http://www.mitadmissions.org/topics/learning/coursework/the_end_of_an_era_1.shtml">Here&#8217;s another take on this topic.</a>)</p>
<div class="zemanta-pixie" style="margin-top: 10px; height: 15px;"><a class="zemanta-pixie-a" title="Reblog this post [with Zemanta]" href="http://reblog.zemanta.com/zemified/16c4697e-0162-4e85-ac13-b671a11e63c0/"><img class="zemanta-pixie-img" style="border: medium none; float: right;" src="http://img.zemanta.com/reblog_e.png?x-id=16c4697e-0162-4e85-ac13-b671a11e63c0" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script src="http://static.zemanta.com/readside/loader.js" type="text/javascript"></script></span></div>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/why-did-mit-switch-from-scheme-to-python/feed</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Software Technologies that I MUST Learn</title>
		<link>http://danweinreb.org/blog/software-technologies-that-i-must-learn</link>
		<comments>http://danweinreb.org/blog/software-technologies-that-i-must-learn#comments</comments>
		<pubDate>Mon, 13 Oct 2008 15:22:46 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Useful Stuff]]></category>

		<guid isPermaLink="false">http://danweinreb.org/blog/?p=69</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelHelpful friends and acquaintences often let me know about exciting new software technologies that I absolutely must know about.  I like learning about exciting new technologies.  Unfortunately, the software world is generating them faster than I can learn them.  Here&#8217;s my list of things I really must learn. Programming languges Dylan: A Lisp-family [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fsoftware-technologies-that-i-must-learn&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/software-technologies-that-i-must-learn" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>Helpful friends and acquaintences often let me know about exciting new software technologies that I absolutely must know about.  I like learning about exciting new technologies.  Unfortunately, the software world is generating them faster than I can learn them.  Here&#8217;s my list of things I really must learn.</p>
<p><strong>Programming languges</strong></p>
<p>Dylan: A Lisp-family language developed by my friends.</p>
<p>ML: How can I be a &#8220;Lisp expert&#8221; and not know ML??</p>
<p>Haskell: Functional programming.  Alan Bawden says this is fundamentally different and I must know it.</p>
<p>Ruby: Up-and-coming popular language.</p>
<p>Subtext: Programming in trees instead of text.  (By Jonathan Edwards, MIT CSAIL.)</p>
<p>Hygenic Macros: A languages feature for doing macros (in the Lisp sense) cleanly.</p>
<p>Groovy: A dynamic language for the Java Virtual Machine.</p>
<p>Ron Garret&#8217;s paper on a module system for Lisp.</p>
<p>F#: Microsoft&#8217;s new function programming language.</p>
<p>LSharp:</p>
<p>Rlisp: A Lisp embedded in Ruby.</p>
<p><strong>Programming tools and libraries</strong></p>
<p>OProfile: The profiling tool for the Lisp implementation that I use.</p>
<p>Krugle:</p>
<p>LispBuilder: Access to SDL from Lisp for game development.</p>
<p>clbuild: An alternative to Lisp&#8217;s asdf-install: helps with download, compilation, and invocation of Lisp apps.</p>
<p><strong><br />
Networking</strong></p>
<p>TRILL: New network protocol designed to solve the problems of the spanning tree.</p>
<p><strong><br />
Databases and Caches</strong></p>
<p>Freebase: &#8220;Open, shared database of the world&#8217;s knowledge.&#8221;  From Metaweb, my old friend Danny Hillis.</p>
<p>CouchDB: Highly scalable document-oriented free DBMS written in Erlang.</p>
<p>Chubby: Google&#8217;s distributed lock system.</p>
<p>Google Sites: Web page design tool</p>
<p>Kompozer: Web page design tool</p>
<p>GORM:  Grails&#8217;s object-relatinal mapping tool, using Hibernate 3.</p>
<p>Terracotta: Clustering/caching tool for Java, making many JVM&#8217;s look like one.</p>
<p>Drizzle: Stripped-down MySQL, useful for caching too.</p>
<p>Whirlycache: A very fast cache</p>
<p>cl-prevalance:</p>
<p>Mongo: A grid-aware object-oriented DBMS from 10gen</p>
<p><strong><br />
Cloud computing</strong></p>
<p>RightSize</p>
<p>Elastra</p>
<p>10gen</p>
<p><strong>Web tools</strong></p>
<p>Rails: (Ruby on Rails) Very popular, highly recommended by many people.</p>
<p>Grails: Rails for Groovy.  Built on GORM and Spring.</p>
<p>Google AppEngine:</p>
<p><strong><br />
Other</strong></p>
<p>VMWare: Can I run Linux on my Windows box?</p>
<p>Software repositories: CPAN, http://planet.plt-scheme.org/, etc.</p>
<p>Jango: A Pandora alternative</p>
<p><em>I&#8217;ll get to them, really, I promise&#8230;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/software-technologies-that-i-must-learn/feed</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>What Conditions (Exceptions) are Really About</title>
		<link>http://danweinreb.org/blog/what-conditions-exceptions-are-really-about</link>
		<comments>http://danweinreb.org/blog/what-conditions-exceptions-are-really-about#comments</comments>
		<pubDate>Mon, 24 Mar 2008 01:22:42 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://dlweinreb.wordpress.com/?p=27</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelThe &#8220;condition&#8221; (exception) feature of Common Lisp is important, but widely misunderstood, as can be seen by the frequent confusion between &#8220;conditions&#8221; and &#8220;errors&#8221;. I&#8217;ve been thinking about conditions and exceptions for many years, and here&#8217;s how I explain them. Notes: I&#8217;m going to avoid using the word &#8220;error&#8221;, which has become overloaded. [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fwhat-conditions-exceptions-are-really-about&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/what-conditions-exceptions-are-really-about" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>The &#8220;condition&#8221; (exception) feature of Common Lisp is important, but widely misunderstood, as can be seen by the frequent confusion between &#8220;conditions&#8221; and &#8220;errors&#8221;.  I&#8217;ve been thinking about conditions and exceptions for many years, and here&#8217;s how I explain them.</p>
<p>Notes: I&#8217;m going to avoid using the word &#8220;error&#8221;, which has become overloaded.  Some of the following applies to Java, but not all; I might write about Java exceptions in the future.  I&#8217;ll omit the use of explicit  catch/throw, for brevity.  I&#8217;m only talking here about the simple heart of the condition feature, not fancy      things like restarts.</p>
<p><b>Contracts, Bugs, and the Failstop Principle</b></p>
<p>Every function has a &#8220;contract&#8221; which defines what the function is supposed to do.  If any function call  violates the contract, the program must be incorrect: a &#8220;bug&#8221; has happened.  The actual incorrect behavior might have started any time before we detect that there&#8217;s a bug.</p>
<p>If a program detects that a bug has happened, it should stop.  That&#8217;s because if it keeps on going, there&#8217;s no way to know what it might do: write the wrong data to a file or database, display wrong answers, hang, etc.  This is called the &#8220;failstop&#8221; principle.</p>
<p>(Exactly what &#8220;stop&#8221; means depends on the context.  An interactive command might return to its event loop.  A server thread might go back to its wait-for-input step.  These are not perfectly safe, since the program might have corrupted transient state before the bug was detected.  A safer way to stop is to kill the entire process.  In Erlang, you only have to kill a thread, since each thread has its own transient state.)<br />
<b><br />
Outcomes</b></p>
<p>The contract of a function specifies, among other things, the possible &#8220;outcomes&#8221; of calling the function.  There is always one &#8220;usual&#8221; or &#8220;straight-line&#8221; kind of outcome, and then there can be zero or more &#8220;unusual&#8221; outcomes.</p>
<p>In Common Lisp, every function call either returns zero of more values, or else signals a condition.  The caller discriminates on which kind of outcome this is by scrutinizing the values returned, or scrutinizing the condition that was signaled.  The contract specifies the circumstances under which each kind of outcome happens, saying what values are returned or what condition object is signaled (plus what side-effects occurred) for each kind of outcome.</p>
<p>For example, suppose we call <code>(open pathname :if-does-not-exist nil)</code>.  Possible kinds of outcome are:</p>
<ul>
<li>It returns a stream object.  This means that the specified file has been opened for input.</li>
<li>It returns <code>nil</code>.  This means that there was no file by this name in the file system.  There are no side-effects.</li>
<li>It signals <code>inappropriate-wildcard</code>.  This means that the pathname had was a wildcard pathname; it doesn&#8217;t make sense to open one.  There are no side-effects.</li>
<li>It signals <code>undefined-logical-host</code>, and the instance&#8217;s <code>undefined-logical-host-name</code> is the name of the logical host.  This means that it was a logical pathname whose host was not found in the set of translations.</li>
</ul>
<p>(There are many other kinds of outcome.  Sadly, Common Lisp does not actually specify what condition classes are signaled.  You own contracts always should!)</p>
<p>If the call to open does any of these things, it is working properly and there is no bug.  If the call to <code>open</code> returns something other than <code>nil </code>or an open-for-input stream to the specified file, or if it signals any other condition class, a bug has happened and the program should stop.</p>
<p>Conditions and bugs are entirely orthogonal.  If you call open (as shown above) with a wildcard pathname, and it signals <code>inappropriate-wildcard</code>, that&#8217;s not a bug; that&#8217;s exactly what it&#8217;s supposed to do.  If you call open and it returns a symbol, that&#8217;s bug, but no condition is signaled.</p>
<p>Commonly, when a function call ends with an unusual outcome, that&#8217;s specified to mean that there were no side-effects.  There&#8217;s nothing theoretically wrong with specifying in the contract that a certain unusual outcome also has some side effects, but it&#8217;s not customary.</p>
<p><b>Tasteful Contract Design</b></p>
<p>When you design a function, you should first think of all the possible kinds of (correct) outcome.  Then you should decide how each outcome will look to the caller: certain specific returned value(s), or certain specific conditions.  This all becomes part of the contract for the function.</p>
<p>The general principle for making this choice is to consider which outcomes are the ones that a programmer is likely to expect and desire.  You can&#8217;t always know for sure: different programmers might call the same function with different expectations.  But it&#8217;s usually not hard to guess accurately.  The &#8220;usual&#8221;, &#8220;straight-line&#8221; outcomes should always be a kind of returned value.  The more unusual outcomes seems like it will be expected and important, the more likely you&#8217;d be to represent it by a kind of returned value than by a condition.  All other unusual outcomes should be indicated by signaling conditions.</p>
<p>The main clue is the appearance of the function call.  That&#8217;s mainly the function&#8217;s name, but it can also include the names of keyword arguments.</p>
<p>For example, <code>(open "/a/b")</code> should be defined to return a value only when it has actually opened a file, in which case it returns a stream.  All other outcomes should be signals of conditions.  However, <code>(open "/a/b" :if-does-not-exist nil)</code> suggests strongly that some outcomes (there&#8217;s no &#8220;b&#8221; in directory &#8220;/a&#8221;, or directory &#8220;/a&#8221; does not exist) should be indicated by returning <code>nil</code>, and conditions should be used for other outcomes.<br />
<b><br />
Why Conditions are Better Than Special Return Values</b></p>
<p>It&#8217;s sometimes tempting to indicate unusual outcomes by having a function return a special value, or by having it return a second value.  However, there are two drawbacks to this.</p>
<p>First, experience over many long years has shown that programmers often forget to check for the special values.  Coding is hard and demands a lot of concentration.  When a programmer is hard at work figuring out how to write an algorithm, it can be difficult to keep in mind all the possible outcomes of every call.  There&#8217;s no excuse for it, but in real life, this is a common bug.</p>
<p>Bruce Eckel, in <i>Thinking in Java, 2nd edition</i>, correctly says:</p>
<p>In C and other earlier languages, there could be several of these formalities, and they were generally established by convention and not as part of the programming language. Typically, you returned a special value or set a flag, and the recipient was supposed to look at the value or the flag and determine that something was amiss. However, as the years passed, it was discovered that programmers who use a library tend to think of themselves as invincible &#8212; as in, &#8220;Yes, errors might happen to others, but not in my code.&#8221; So, not too surprisingly, they wouldn&#8217;t check for the error conditions (and sometimes the error conditions were too silly to check for [such as all the error values from printf]). If you were thorough enough to check for an error every time you called a method, your code could turn into an unreadable nightmare. Because programmers could still coax systems out of these languages they were resistant to admitting the truth: This approach to handling errors was a major limitation to creating large, robust, maintainable programs.</p>
<p>If an algorithm forgets to check for the special values, it will proceed as if the usual outcome happened.  This means that the program is malfunctioning.  A bug has happened but it has not been detected.</p>
<p>But if that unusual outcome is expressed as a signal of a condition, and the programmer forgets to handle it, the program will stop.  This is what we want: failstop behavior.</p>
<p>(Exactly what &#8220;stop&#8221; means depends on context.  In a server, there would probably be a handler-bind near the base of the stack that handles all conditions.  This &#8220;ultimate handler&#8221; is called when a bug has been detected.  It might write a stack trace to a log file, and then cause the thread to be restarted, for example.)</p>
<p>Second, even if you do remember to check for the special value, it often makes the program cluttered and harder to read.  This is particularly annoying in Lisp, where it&#8217;s customary to write applicative forms where arguments to one form are themselves non-trivial forms.</p>
<p>I only have room here for a short example.  The problems discussed above come up more often, and are harder to deal with, in much larger programs.</p>
<p>Suppose we have a configuration module that associates keys with URL&#8217;s.  Looking up a key has two possible outcomes: the URL is found (usual) and no URL is found (unusual).  The function <code>url-host-name</code> extracts the host name from an URL. If the URL does not specify a host name, that&#8217;s an unusual outcome.  Finally, <code>make-host</code> creates and returns a host object, with the given host name.</p>
<p>We want to write a new function, <code>get-host-from-configuration</code>, which takes a configuration and key, and returns the host name of the specified configuration entry.  There are two possible outcomes: the host, or an indication that we could not obtain it.</p>
<p>Version 1 disregards unusual outcomes:</p>
<pre>(defun get-host-from-configuration (configuration key)
  "Returns the host associated with the key and the configuration."
  (make-host :name (url-host-name (read-url configuration key))))</pre>
<p>Version 2 indicates unusual outcomes by returning <code>nil</code>:</p>
<pre>
(defun get-host-from-configuration (configuration key)
  "Returns the host associated with the key and the configuration,
or nil if it cannot be obtained."
  (let ((url (read-url configuration key)))
    (when url
      (let ((host-name (url-host-name url)))
        (when host-name
          (make-host :name host-name))))))
</pre>
<p>Version 3 uses conditions:</p>
<pre>
(defun get-host-from-configuration (configuration key)
  "Returns the host associated with the key and the configuration,
  signal host-not-in-config if the host cannot be found."
  (handler-case
        (make-host :name (url-host-name (read-url configuration key)))
    ((configuration-entry-not-found url-has-no-host) ()
        (error 'cannot-make-host-from-key :key key))))
</pre>
<p>Version 1 is nice and simple, but it doesn&#8217;t take into account the possibility of the unusual outcomes of its callees.  Its contract cannot possibly be fulfilled.</p>
<p>Version 2 works, but it loses the applicative form.  Every time we call a function, we have to stop, give the result a name, and check it before we can go on.</p>
<p>Version 3 keeps the applicative form.  As long as everything has the usual outcome, it&#8217;s just like the simple code in Version 1.  The &#8220;straight-line&#8221; code path is all in one place and easy to see.  The infrequent unusual condition handlers are out of the way.</p>
<p><b>Conditions at the Right Level of Abstraction</b></p>
<p>You may be thinking: why not fix Version 1 by keeping the code, and just changing its contract to say</p>
<p>&#8220;Returns the host associated with the key and the configuration, signals <code>configuration-entry-not-found</code> if the URL was not found in the configuration, and signals <code>url-has-no-host</code> if the URL doesn&#8217;t have a host.&#8221;</p>
<p>In other words, we could make the callees use conditions, as with version 3, but just let the conditions propagate to the caller.</p>
<p>The problem with this is that it&#8217;s a modularity violation.  The caller of <code>get-host-from-configuration</code> has no business knowing that there are URL&#8217;s involved at all.  That&#8217;s an underlying implementation detail.  Instead, <code>get-host-from-configuration</code> should indicate the unusual outcome, that it can&#8217;t make the host object, by signaling the <code>cannot-make-host-from-key</code> condition.  It&#8217;s OK for the condition object to contain the key, since our caller clearly knows about the concept of keys since that&#8217;s an argument to <code>get-host-from-configuration</code>.</p>
<p>Similarly, it&#8217;s good for the <code>read-url</code> function applied to a configuration to indicate that it can&#8217;t find an entry by signaling <code>configuration-entry-not-found</code> rather than, say, <code>file-not-found</code> if the whole configuration file was missing.  The caller of <code>read-url</code> has no business knowing whether the configuration is stored in a file or a database.  We might even have two subclasses of configuration, <code>file-configuration</code> and <code>database-configuration</code>, but this would be hidden from the caller of <code>get-host-from-configuration</code>.  Whether the configuration is stored in a file or a database is an internal implementation detail.</p>
<p><b>condition, serious-condition, and error Are Meaningless</b></p>
<p>Common Lisp defines three base condition classes named <code>condition</code>, <code>serious-condition</code>, and <code>error</code>.  This is based on the misconception that you can tell whether the signaling of a condition is an &#8220;error&#8221; (bug) simply by knowing the class.  But you can&#8217;t.  Whether the signaling of a condition is a bug or not depends entirely on whether the function signaling it is defined to do so, or not.  If I were designing a new dialect of Lisp, I would omit the classes <code>serious-condition</code> and <code>error</code>.</p>
<p><b>Why This Philosophy is Unconventional</b></p>
<p>Most explanations of conditions put little or no emphasis on functions having contracts that specify conditions.  Few other explanations refer to the propensity of programmers to neglect to check special &#8220;error codes&#8221;.</p>
<p>Major Lisp texts, such as &#8220;Practical Common Lisp&#8221; and &#8220;Common Lisp: The Language, 2nd Edition&#8221; start off by acknowledging that signaling does not always mean that there&#8217;s an &#8220;error&#8221;, but they soon give up on that distinction.  The word &#8220;error&#8221; is often used to sometimes mean what I call an &#8220;unusual outcome&#8221; and other times used to mean what I call a &#8220;bug&#8221;.  I see these as extremely different phenomena that must be carefully distinguished.</p>
<p>The fact that the usual function for signaling a condition is called <code>error </code>greatly amplifies the confusion.  If I were designing a new Lisp dialect, I would not call it that.</p>
<p>Bruce Eckel&#8217;s book says:</p>
<p>With an exceptional condition, you cannot continue processing because you don&#8217;t have the information necessary to deal with the problem in the current context. All you can do is jump out of the current context and relegate that problem to a higher context. This is what happens when you throw an exception.</p>
<p>As you see, that&#8217;s not how I would explain it at all.  An unusual outcomes isn&#8217;t even necessarily a &#8220;problem&#8221;.  It doesn&#8217;t mean you &#8220;cannot continue processing&#8221; any more than returning from the function means that.</p>
<p>Joel Spolsky <a href="http://www.joelonsoftware.com/items/2003/10/13.html" title="Joel" target="_blank">doesn&#8217;t like exceptions at all</a>.  He considers them like &#8220;goto&#8221; statements, which everybody &#8220;considers harmful&#8221;, whereas I think that structured non-local exits do not have the problems cited in the &#8220;considered harmful&#8221; paper.  He objects that &#8220;there is no way to see which exceptions might be thrown and from where&#8221;.  But how are you supposed to program with functions whose contracts you do not know, exceptions or no exceptions?  He says &#8220;they create too many possible exit points&#8221;; but whether you express unusual outcomes with exceptions or with special returned values, there are just the same number of them.  He advocates using error codes, even though he admits that it makes programs far bulkier and makes it impossible to nest function calls.</p>
<p><b>Implementation and Portability Considerations</b></p>
<p>The Common Lisp specification makes tradeoffs between clean contracts and speed.  For example, the addition function &#8220;+&#8221; ideally ought to be defined to signal a condition when either argument is a symbol.  But, in order to allow generation of fast code on non-specialized hardware, its contract says that given a symbol, it may either signal, or return some integer value.</p>
<p>Some contracts in Common Lisp are deliberately incomplete in order to allow some implementations to add non-standard extensions.</p>
<p>Many contracts in Common Lisp do not specify particular condition classes to be signaled, but rather erely say that some outcome&#8217;s behavior is &#8220;a condition is signaled&#8221; without specifying a particular condition class nor instance variable values.</p>
<p><b>Topics For the Future</b></p>
<p><code>unwind-protect</code>, unhandled conditions in cleanup handlers, chained conditions, Java exceptions, debugging, <code>handler-bind</code>, handling all condition classes, <code>*break-on-signal*</code>, polymorphism, <code>with-error-context</code>, condition names should say what happened, not where it happened.</p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/what-conditions-exceptions-are-really-about/feed</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Notes on the book: Dreaming in Code</title>
		<link>http://danweinreb.org/blog/notes-on-the-book-dreaming-in-code</link>
		<comments>http://danweinreb.org/blog/notes-on-the-book-dreaming-in-code#comments</comments>
		<pubDate>Thu, 27 Dec 2007 14:08:20 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Book]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Chandler]]></category>
		<category><![CDATA[PIM]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://dlweinreb.wordpress.com/2007/12/27/notes-on-the-book-dreaming-in-code/</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelI just finished reading an amazing book: &#8220;Dreaming in Code&#8221; by Scott Rosenberg. Like many good, recent non-fiction books, it alternates between a specific narrative with colorful real people, and general background information. In this case, it&#8217;s the story of Chandler, a personal information management tool, and the team who are building it, [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fnotes-on-the-book-dreaming-in-code&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/notes-on-the-book-dreaming-in-code" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>I just finished reading an amazing book: &#8220;Dreaming in Code&#8221; by Scott Rosenberg.  Like many good, recent non-fiction books, it alternates between a specific narrative with colorful real people, and general background information.  In this case, it&#8217;s the story of Chandler, a personal information management tool, and the team who are building it, led by Mitch Kapor.</p>
<p>The general background explains far more about real, contemporary software, how it is built, and what it&#8217;s all about, than anything I&#8217;ve read before.  Everyone learning to be a software engineer, or who wants to understand what software engineers actually do, should read this book.</p>
<p>In only 355 pages, Rosenberg discusses, in clear language that&#8217;s easy to follow, at least the following:</p>
<ul>
<li>What working on a software project in a team is like, the subjective experience</li>
<li>Open software, and the &#8220;Cathedral vs. Baazar&#8221; concept</li>
<li>Doug Englebart&#8217;s ideas (very germane to Chandler)</li>
<li>Famous software fiascoes</li>
<li>Computer languages, especially Python and how it compares to others</li>
<li>Reusable software, software libraries, build versus buy</li>
<li>What &#8220;geek&#8221; really means</li>
<li>CVS, Bugzilla, and Wikis</li>
<li>Why user interfaces are so hard to design</li>
<li>Dependencies between parts of a system and how they block work</li>
<li>Release management and scheduling</li>
<li>Specifications and their nature</li>
<li>Layers of abstraction</li>
<li>Scaffolding</li>
<li>Code reviews</li>
<li>WebDAV and CalDAV</li>
<li>Microsoft FUD</li>
<li>Requirements analysis</li>
<li>Methodologies: waterfall, agile</li>
<li>The gist of No Silver Bullet and The Mythical Man-Month</li>
<li>Ruby on Rails</li>
<li>Software engineering, its history and what it means</li>
<li>Complexity</li>
<li>Late binding</li>
<li>Object-oriented programming</li>
<li>Recursion</li>
<li>The halting problem</li>
</ul>
<p>The story of Chandler and the team is compelling and instructive.  On page 173 of the book, he says:  &#8220;By now, I know, any software developer reading this volume has likely thrown it across the room in despair, thinking, &#8216;Stop the madness! They&#8217;re making every mistake in the book!&#8217;&#8221;  I did indeed feel that way by page 173.  Here&#8217;s my sense of what went wrong, based on the account in the book:</p>
<ul>
<li>They did not have one architect (Brooks makes a very good point about why there should be a single person)</li>
<li>They didn&#8217;t work out the architecture in advance, and they went back and changed it many times</li>
<li>They had a very flexible data concept/model, in which items change type frequently in a user-visible way, which they didn&#8217;t work out until quite late</li>
<li>They kept changing their mind about their UI substrate: wxWidgets?  Mozilla internals?</li>
<li>The software ecosystem changed around them after all those years, and using a Web UI now made sense, but it was too late for them</li>
<li>They could not figure out what database technology to use (they finally decided not to use the Zope Object Database, although their reasons for that decision don&#8217;t impress me)</li>
<li>It was originally supposed to be peer-to-peer, but they could not figure out how to make that work, so they changed it to be server-based, a major change very late in the design</li>
<li>They had to design a security model for all this</li>
<li>It was all extensible, which is great but takes a lot of work to do right</li>
<li>There were complicated semantic issues with sharing, &#8220;chain-sharing&#8221;, etc. which were not worked out early.</li>
<li>They wanted to have extensional and intensional collections, like iTunes, but also wanted to combine the two (the so-called &#8220;exclude Bob Marley&#8221; feature), which makes the semantics a lot harder</li>
<li>Their internal terminology was inconsistent, symptomatic of a lack of architectural integrity</li>
<li>They did serious requirement analysis only late in the project</li>
<li>It was putatively open-source, but it was much too immature to really get outside developers involved</li>
<li>They were too focused on doing &#8220;the right thing&#8221; instead of getting something out fast; see Gabriel&#8217;s &#8220;Worse is Better&#8221; paper</li>
<li>They released much too early, partly because of the glare of publicity due to Mitch Kapor&#8217;s involvement</li>
</ul>
<p>I see that they are still in &#8220;preview&#8221; releases.  This has been going on for six years now!  They have no projected release date for 1.0.  It will be free, under the Apache license.</p>
<p>I have always wanted a good personal information manager, and a lot about Chandler looks very promising. Someday I may be a happy user.  Right now, I think I&#8217;ll wait until release 1.0.</p>
<p>I hope they have moved beyond the problems illustrated in the book and are running smoothly now.  Kudos to the whole Chandler team for letting Rosenberg be so involved, being so honest with him, and letting him produce this unique, spectacular book.</p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/notes-on-the-book-dreaming-in-code/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Be a Mentor</title>
		<link>http://danweinreb.org/blog/be-a-mentor</link>
		<comments>http://danweinreb.org/blog/be-a-mentor#comments</comments>
		<pubDate>Tue, 25 Dec 2007 15:58:08 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Mentor]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://dlweinreb.wordpress.com/2007/12/25/be-a-mentor/</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelDeveloping software can&#8217;t be learned in a classroom. To be sure, there are plenty of things that you can learn in a classroom that are invaluable. But if you want to be a software engineer, you have to learn by doing. When I showed up at M.I.T. as a freshman, I had learned [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fbe-a-mentor&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/be-a-mentor" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>Developing software can&#8217;t be learned in a classroom.  To be sure, there are plenty of things that you can learn in a classroom that are invaluable.  But if you want to be a software engineer, you have to learn by doing.</p>
<p>When I showed up at M.I.T. as a freshman, I had learned computer programming at summer schools.  My regular school didn&#8217;t have any computers (this was the early 1970&#8242;s).  The only programs I had ever written were homework assignments, and little toys for myself.  I had never worked on, or even read, anything large, or anything that needed to be maintained over time.</p>
<p>I was set to work writing an Emacs in Lisp for the Lisp machine.  This was quite a big change!  During my time as an undergraduate I wrote a lot of system software for the Lisp machine (and a little for the ITS timesharing system), and I think it was pretty good code, better as the years went by. But when I look back, I marvel that I was able to get going so quickly.  I&#8217;m a pretty bright person but no genius; I know dozens of people personally who are way smarter than me.  I now attribute it to two things.  First, I read lots and lots of real software, studying it line by line.  Second, I had a great mentor.</p>
<p>After Richard Greenblatt hired me at the M.I.T. Artificial Intelligence lab, my first task was to learn Lisp.  I didn&#8217;t know how to go about doing that effectively.  Greenblatt told me to write a chess program, and I tried that, but I found myself doing low-level array stuff (how does a knight move?) and it was just like programming in Basic again.  I had observed that this guy Dave Moon seemed to be one of the very respected hackers (I use the word in its original sense) at the Lab, and although he seemed a bit unapproachable at the time, I asked him how to learn Lisp, and he told me to write a symbolic differentiator.  That was a much better approach.</p>
<p>Moon was also working on the Lisp machine software, and there were only a few of us, so he spent considerable time helping me get up to speed.  He reviewed all my code and gave me extensive feedback, and he answered all my questions.  I read all of his code and did my best to emulate it.  We worked very closely, even sometimes sitting at the same console taking turns typing.</p>
<p>For me, it was an apprenticeship.  Although the classic &#8220;apprentice&#8221; that you read about in historical books spends years doing junky, boring work, whereas I was doing the good stuff right away.  Although my reasons for personal bias are obvious, I think Dave Moon is one of the dozen best programmers in the world, and I know many others who have similar respect for his depth of understanding as well as coding abilities.  To have stumbled upon having him as a mentor is one of the luckiest things that has ever happened to me.</p>
<p>I have tried to &#8220;give back&#8221; the good fortune that I&#8217;ve had.  I&#8217;ve never had a full-time apprentice, but I have tried to help other hackers whom I&#8217;ve worked with.  And this year I&#8217;m helping to teach a class in Java Distributed Programming at Harvard Extension School, providing several students with the first detailed code reviews they&#8217;ve ever had.  I&#8217;ve also recently submitted my name to an M.I.T. mentoring initiative, volunteering to be a mentor.  We&#8217;ll see what happens with that.</p>
<p>I&#8217;ve learned a lot from many people.  Prof. Gerry Sussman at M.I.T. is a superb teacher, who has lots of apprentices.  I never apprenticed under him, but I learned a lot from his classes and many personal conversations.  Guy Steele and Tom Knight were also particularly influential.  And I keep learning from my co-workers.</p>
<p>You don&#8217;t have to be a stellar hacker to be a fine mentor.  Give younger people an opportunity to do real, production programming.  Keep a close eye on their work and help them improve it.  Help them learn the lessons that can&#8217;t be taught in classrooms: how do real software projects go, how do you work well with other hackers on a team, why it&#8217;s so important to strive for simplicity, and so on.</p>
<p>Ideally, find a promising beginner who you&#8217;ll be working with for a year or more, someone you&#8217;ll enjoy spending a lot of time with, and start mentoring him or her.  You don&#8217;t have to say anything or make any formal offer.  Just do it, and see how it goes.</p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/be-a-mentor/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>The Scala programming language: My First Impressions</title>
		<link>http://danweinreb.org/blog/the-scala-programming-language-my-first-impressions</link>
		<comments>http://danweinreb.org/blog/the-scala-programming-language-my-first-impressions#comments</comments>
		<pubDate>Tue, 25 Dec 2007 14:40:12 +0000</pubDate>
		<dc:creator>Dan Weinreb</dc:creator>
				<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://dlweinreb.wordpress.com/2007/12/25/the-scala-programming-language-my-first-impressions/</guid>
		<description><![CDATA[news and informationbusiness,health,entertainment,technology&#160;automotive,business,crime,health,life,politics,science,technology,travelI keep coming across praise for a new programming language called Scala. I looked into it a bit, and here are my first impressions. I have not written any programs in it, so I am hardly even a beginner, let along an expert. My own opinions are in parentheses. Please comment on this [...]]]></description>
			<content:encoded><![CDATA[<div style="height:33px; padding-top:2px; padding-bottom:2px; clear:both;" class="vas_pro_2"><div style="float:left; width:100px; " class="vas_pro_2_facebook_like"> 
				<iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdanweinreb.org%2Fblog%2Fthe-scala-programming-language-my-first-impressions&amp;layout=button_count&amp;show_faces=false&amp;width=100&amp;action=like&amp;colorscheme=light&amp;height=27" 
					scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:27px;" allowTransparency="true"></iframe>
			</div><div style="float:left; width:90px; padding-left:10px;" class="vas_pro_2_google1"> 
				<g:plusone size="medium" href="http://danweinreb.org/blog/the-scala-programming-language-my-first-impressions" ></g:plusone>
			</div></div>
		<div style="display:none;"><a href="http://www.24wn.com">news and information</a><a href="http://www.forum1000.com">business,health,entertainment,technology</a>&nbsp;<a href="http://news365online.com">automotive,business,crime,health,life,politics,science,technology,travel</a></div><div style="clear:both;"></div><p>I keep coming across praise for a new programming language called <a href="http://www.scala-lang.org" title="Scala" target="_blank">Scala</a>. I looked into it a bit,   and here are my first impressions.  I have not written any programs in it, so I am hardly even a beginner, let along an expert.  My own opinions are in parentheses. Please comment on this post to correct my errors.</p>
<p>I started with the JavaPolis &#8217;07 <a href="http://www.parleys.com/display/PARLEYS/Interview+with+Martin+Odersky+at+JavaPolis%2707" title="interview" target="_blank">interview</a> with Martin Odersky.  (He&#8217;s the kind of person I like: clear, cogent, practical, charming, and modest.)  I then downloaded it.</p>
<p>History: The key inventor is <a href="http://lamp.epfl.ch/~odersky/" title="Martin Odersky" target="_blank">Martin Odersky</a>, who heads the programming research group at Ecole Polytechnique Federale de Lausanne as a full professor, and was one of the designers of Java generics.  He was a student of Wirth and came from the Modula-2 tradition, but later got interested in functional programming, and is now associate editor of the Journal of Functional Programming.  He&#8217;s been working on Scala for over five years.  He originally used Scala in classes, teaching Java first, and then Scala in the next year as a &#8220;power Java&#8221;.  The first public release was in 2004, and he revised it substantially in 2006.  There has been a series of versions, maintained with back-compatibility and a deprecation protocol.  The current version is 2.6.</p>
<p>What&#8217;s it for?: It is intended to be a general-purpose language that could replace Java.  So far it has primarily been used for web-related applications.  The first industrial users were a company called Sygneca in the U.K., who have used to build web sites for agencies of the British government.  Perhaps the best-known development has been David Pollack&#8217;s <a href="http://liftweb.net/" title="Liftweb" target="_blank">Liftweb</a>, a web framework along the lines of Rails, which is getting a lot of attention and has many committers.  See .</p>
<p>Documentation: Odersky recommends starting with &#8220;<a href="http://www.artima.com/scalazine/articles/steps.html" title="First Steps to Scala" target="_blank">First Steps To Scala</a>&#8221; (also in the distribution).  Then, you can move on to the book &#8220;Programming in Scala&#8221;, by himself and others, which just came out on Dec 12 (two weeks ago, as I write this).  You can <a href="http://www.artima.com/shop/forsale" title="buy" target="_blank">get the PDF</a> for US$22.50.  It assumes you know Java.  The distribution comes with a reference manual.</p>
<p>Functional programming: Scala is intended to be a fusion of functional programming and object-oriented programming, rather than a &#8220;pure&#8221; function language like Haskell or ML.  Ordinary imperative programming works fine.  Objects can be mutable or immutable.  The latter is preferred when it&#8217;s possible, since it needs no concurrency control.  Also, these days it&#8217;s faster to make new objects and allow them to be efficiently GC&#8217;ed, than incur the GC overhead that results when you mutate an existing object (interesting point!).  There are mutable arrays, but immutable (parameterized) List objects. (I am entertained that the infix operator &#8220;::&#8221;, which makes a new List with an element prepended, is pronounced &#8220;cons&#8221;!) &#8220;Nil&#8221; creates an empty list (unlike Lisp, lists are first-class).  The lexeme &#8220;=&gt;&#8221; is used to define anonymous functions (what Lisp people call lambda expressions), so you can do mylist.filter(s =&gt; s.length = 4).  There are also immutable &#8220;tuples&#8221; whose elements can be of any type and which have a very simple creation syntax: (52, &#8220;Locust&#8221;).  (These are even more like Lisp lists).  One thing you&#8217;d use this for is multiple-value return.</p>
<p>Object-oriented programming: Notice how few explicit type declarations there are:<br />
<code><br />
class SimpleGreeter {<br />
val greeting = "Hello, world!"<br />
def greet() = println(greeting)<br />
}</code></p>
<p><code><br />
val g = new SimpleGreeter<br />
g.greet()<br />
</code></p>
<p>There are no static fields or methods.  Instead, you use singletons.  The concept of singletons is built into the language, so the syntax is concise and stylized.  (I&#8217;ve said before that the famous &#8220;Design Patterns&#8221; are often just conventions that make up for things that the language cannot do itself.  Here&#8217;s another example of a pattern that&#8217;s no longer needed as a pattern.)  There are &#8220;traits&#8221;, which are like Java interfaces except that they can define default method implementations.  Although Scala is &#8220;single inheritance of implementation&#8221; like Java, there&#8217;s a way to use traits that provides a simple &#8220;mixin&#8221; facility.</p>
<p>Interpreter: Scala has an interactive interpreter (what Lisp people call a &#8220;read-eval-print loop&#8221;) (right there, we&#8217;re way ahead of Java!).  You can define variables without specifying the type; it infers it.  Here&#8217;s a simple function definition:<br />
<code>   def max(x: Int, y: Int): Int = if (x &lt; y) y else x</code><br />
Parameter types are not inferred, so they must be specified.  But in some cases, including this one, the result type is inferred.</p>
<p>Concurrency: There is a library trait called &#8220;Actor&#8221;.  It&#8217;s based on the concepts in <a href="http://lampwww.epfl.ch/~odersky/papers/jmlc06.pdf" target="_blank">this paper</a> and <a href="http://lamp.epfl.ch/%7Ephaller/doc/haller07coord.pdf" target="_blank">this paper</a>, which I have not yet read.  It looks like it&#8217;s oriented around asynchronous messaging.</p>
<p>Sharing of libraries: There is a system called <a href="http://www.lexspoon.org/sbaz/manual.html" title="sbaz" target="_blank">Scala Bazaars</a>, or &#8220;sbaz&#8221;, to help the open source community share libraries.  There appear to be around 250 contributions already.</p>
<p>Some other interesting features: The syntax of XML is embedded in Scala.  There are primitives for pattern matching (what Lisp people would call <a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_destru.htm#destructuring-bind" title="destructuring" target="_blank">destructuring</a>).  There are user-defined annotations.</p>
<p>Implementation: The main Scala compiler produces Java class files; It can operate seamlessly with Java.  (This means you get an excellent JIT compiler, an excellent GC, and lots of libraries, a huge plus for a new language.)  There&#8217;s also a compiler that makes binaries for the .NET CLR.</p>
<p>Interactive development environments: It comes with GNU Emacs support, and there are plugins available for <a href="http://www.eclipse.org/" title="Eclipse" target="_blank">Eclipse </a>and <a href="http://www.jetbrains.com/idea/" title="IntelliJ IDEA" target="_blank">IntelliJ IDEA</a>.</p>
<p>Persistence: It works with the <a href="http://www.db4o.com/" title="db40" target="_blank">db40 </a>object-oriented database system.</p>
<p>Summary: I feel that the way functional, object-oriented, and imperative programming are combined in Scala is much like the way they are combined in Lisp.  As compared to Lisp:</p>
<ul>
<li>conventional syntax;  more approachable to many people</li>
<li>no Lisp-like macros</li>
<li>much cleaner (anything is cleaner than Common Lisp, of course)</li>
<li>statically typed with inferencing: the best of static typing without the worst parts</li>
<li>no ability to incrementally recompile and re-run (as far as I can see)</li>
</ul>
<p>The emphasis on immutability and the Actor class also makes me think of Erlang, but I know too little about both Scala and Erlang to venture further comments.</p>
<p>It looks extremely promising.  I&#8217;ll be keeping an eye on this.</p>
]]></content:encoded>
			<wfw:commentRss>http://danweinreb.org/blog/the-scala-programming-language-my-first-impressions/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>

