<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en" xml:base="http://programmingzen.com/wp-atom.php">
	<title type="text">Zen and the Art of Programming</title>
	<subtitle type="text">By Antonio Cangiano, Software Engineer &amp; Technical Evangelist at IBM</subtitle>

	<updated>2010-07-21T22:12:55Z</updated>

	<link rel="alternate" type="text/html" href="http://programmingzen.com" />
	<id>http://programmingzen.com/feed/atom/</id>
	

	<generator uri="http://wordpress.org/" version="3.0">WordPress</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ZenAndTheArtOfRubyProgramming" /><feedburner:info uri="zenandtheartofrubyprogramming" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[The Great Ruby Shootout (July 2010)]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/Agu4ePRDQsM/" />
		<id>http://programmingzen.com/?p=1233</id>
		<updated>2010-07-21T22:12:55Z</updated>
		<published>2010-07-19T18:12:31Z</published>
		<category scheme="http://programmingzen.com" term="Ruby" /><category scheme="http://programmingzen.com" term="Ruby Benchmark Suite" />		<summary type="html"><![CDATA[The Great Ruby Shootout measures the performance of several Ruby implementations by testing them against a series of synthetic benchmarks. Recently I ran Mac and Windows shootouts as well, which tested a handful of implementations. However this article reports on the results of extensive benchmark testing of eight different Ruby implementations on Linux. The setup [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/">&lt;p&gt;The Great Ruby Shootout measures the performance of several Ruby implementations by testing them against a series of synthetic benchmarks. Recently I ran &lt;a href="http://programmingzen.com/2010/05/16/benchmarking-macruby-0-6/"&gt;Mac&lt;/a&gt; and &lt;a href="http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/"&gt;Windows&lt;/a&gt; shootouts as well, which tested a handful of implementations. However this article reports on the results of extensive benchmark testing of eight different Ruby implementations on Linux.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The setup&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For this shootout I included a subset of the &lt;a href="http://github.com/acangiano/ruby-benchmark-suite"&gt;Ruby Benchmark Suite&lt;/a&gt;. I opted to primarily exclude tests that were executed in fractions of a second in most VMs, focusing instead of more substantial benchmarks (several of which came from the &lt;a href="http://shootout.alioth.debian.org/"&gt;Computer Language Benchmarks Game&lt;/a&gt;). The best times and least memory allocations out of five runs are reported here for each benchmark.&lt;/p&gt;
&lt;p&gt;All tests were run on Ubuntu 10.4 LTS x86_64, on an Intel Core 2 Quad Q6600 2.40 GHz, 8 GB DDR2 RAM, with two 500 GB 7200 rpm disks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8 implementations&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The implementations tested were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ruby 1.8.7 p299&lt;/li&gt;
&lt;li&gt;Ruby 1.9.1 p378&lt;/li&gt;
&lt;li&gt;Ruby 1.9.2 RC2&lt;/li&gt;
&lt;li&gt;IronRuby 1.0 (Mono 2.4.4)&lt;/li&gt;
&lt;li&gt;JRuby 1.5.1 (Java HotSpot(TM) 64-Bit Server VM 1.6.0_20)&lt;/li&gt;
&lt;li&gt;MagLev (rev 23832)&lt;/li&gt;
&lt;li&gt;Ruby Enterprise Edition 2010.02&lt;/li&gt;
&lt;li&gt;Rubinius 1.0.1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;JRuby was run with the &amp;#8211;fast and &amp;#8211;server optimization flags.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Synthetic benchmarks cannot predict how fast your programs will be when dealing with a particular implementation. They provide an (entertaining) educated guess, but you shouldn’t draw overly definitive conclusions from them. The values reported here should be assumed to be characteristic of server-side &amp;mdash; and long running &amp;mdash; processes; they should be taken with a grain of salt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Time Results&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Please find below the execution times for the selected tests. Timeouts indicate that the execution of a single iteration for a given test took more than 300 seconds and had to be interrupted. Bold, green values indicate the best performer out of each test.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Warning: The bm_primes.rb benchmark was originally written to aid the development of the Prime class. As such in 1.9.2 it was rewritten in C, which makes it a poor representation of implementation performance. This benchmark will removed in the future.&lt;/em&gt; &lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/linux-time-table1.png" alt="Time Table on Linux" /&gt;&lt;/p&gt;
&lt;p&gt;If you are not interested in the individual test results, the information presented in the table above is summarized directly below:&lt;/p&gt;
&lt;pre class="highlight"&gt;
  Ruby 1.9.2         JRuby
Min.   : 0.013   Min.   : 0.382
1st Qu.: 3.258   1st Qu.: 3.051
Median : 4.543   Median : 4.997
Mean   : 9.262   Mean   : 9.180
3rd Qu.: 8.573   3rd Qu.: 8.969
Max.   :45.009   Max.   :48.850

    MagLev         Ruby 1.9.1
Min.   : 0.351   Min.   : 0.015
1st Qu.: 2.140   1st Qu.: 3.387
Median : 6.069   Median : 6.205
Mean   : 9.100   Mean   :10.860
3rd Qu.: 9.266   3rd Qu.:11.559
Max.   :51.221   Max.   :46.849

 Ruby 1.8.7         IronRuby
Min.   : 0.708   Min.   :  3.601
1st Qu.: 5.102   1st Qu.: 10.505
Median : 8.380   Median : 12.912
Mean   :18.785   Mean   : 26.539
3rd Qu.:24.793   3rd Qu.: 36.115
Max.   :75.653   Max.   :135.204

   Rubinius           REE
Min.   : 0.484   Min.   : 0.584
1st Qu.: 3.087   1st Qu.: 4.343
Median : 9.636   Median : 6.660
Mean   :13.232   Mean   :15.036
3rd Qu.:17.674   3rd Qu.:21.336
Max.   :73.050   Max.   :61.960
&lt;/pre&gt;
&lt;p&gt;For the sake of convenience, I also produced a box plot from the successful data points:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/linux-time-plot.png" alt="Box plot of times"/&gt;&lt;/p&gt;
&lt;p&gt;There are a few considerations based on these results that I feel are worth mentioning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As you can see Ruby 1.9, JRuby and MagLev converge towards a similar performance level according to these tests.&lt;/li&gt;
&lt;li&gt;Ruby 1.9.2 manages to squeeze in a bit of extra speed when compared to Ruby 1.9.1 (which is a welcome improvement).&lt;/li&gt;
&lt;li&gt;Ruby 1.9 seems to be either much faster than Ruby 1.8 or roughly as fast, depending on the test. This appears to be in line with what I&amp;#8217;ve seen in real world programs. There are programs that will only receive a 10-20% boost from 1.9, while others improve drastically. The results really depends on what a program spends its time doing.&lt;/li&gt;
&lt;li&gt;Performance wise, Rubinius is really starting to be a much more serious contender.&lt;/li&gt;
&lt;li&gt;Ruby Enterprise Edition is slightly faster than Ruby 1.8.7, to the extent where this is clearly visible in almost all of the tests.&lt;/li&gt;
&lt;li&gt;IronRuby running on Mono was the worse of the lot.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Memory Results&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The following table shows the approximate memory consumption for each implementation when running each benchmark:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/linux-memory-table.png" alt="Memory allocation on Linux" /&gt;&lt;/p&gt;
&lt;p&gt;Summarized:&lt;/p&gt;
&lt;pre class="highlight"&gt;
  Ruby 1.9.2        Ruby 1.9.1
Min.   :  4.320   Min.   :  4.580
1st Qu.:  4.378   1st Qu.:  4.695
Median :  6.285   Median :  6.920
Mean   : 20.795   Mean   : 15.669
3rd Qu.: 10.162   3rd Qu.: 11.383
Max.   :171.500   Max.   :100.570

   Ruby 1.8            REE
Min.   :  3.040   Min.   :  8.220
1st Qu.:  4.290   1st Qu.:  9.682
Median :  7.745   Median : 15.565
Mean   : 20.698   Mean   : 27.014
3rd Qu.: 11.273   3rd Qu.: 38.620
Max.   :103.520   Max.   :125.910

  Rubinius           MagLev
Min.   : 37.63   Min.   : 81.74
1st Qu.: 39.78   1st Qu.: 82.52
Median : 45.48   Median : 83.53
Mean   : 65.70   Mean   : 96.29
3rd Qu.: 58.22   3rd Qu.: 98.10
Max.   :215.33   Max.   :175.85   

    JRuby
Min.   : 49.04
1st Qu.: 71.23
Median :176.72
Mean   :169.41
3rd Qu.:209.04
Max.   :404.06
&lt;/pre&gt;
&lt;p&gt;And finally, in graph form:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/linux-memory-plot1.png" alt="Memory Box Plot" /&gt;&lt;/p&gt;
&lt;p&gt;A few considerations on memory:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Memory readings for IronRuby were not available, so they were not included.&lt;/li&gt;
&lt;li&gt;Ruby 1.9.2 uses the least amount of memory (as one might expect).&lt;/li&gt;
&lt;li&gt;JRuby was by far the most memory intensive of the group.&lt;/li&gt;
&lt;li&gt;Ruby Enterprise Edition used less memory than 1.8.7 in a few tests, but overall was more memory hungry than 1.8.7. This is really odd and entirely unexpected.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Linux Vs. Windows&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This shootout and the Windows one were both performed on the same machine, thus we can compare how the same implementation perform under different operating systems. The only adjustment that’s required is the timeout. Every result longer than 60 seconds from this shootout needs to be considered a timeout, because the previous shootout did so as well.&lt;/p&gt;
&lt;p&gt;It is commonly believed that Ruby performs much better on Linux than on Windows (with the exception of IronRuby). Let&amp;#8217;s find out if these test results confirm that notion.&lt;/p&gt;
&lt;p&gt;Ruby 1.8.7:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-187-table.png" alt="Ruby 1.8.7 on Linux and Windows" /&gt;&lt;/p&gt;
&lt;p&gt;Ruby 1.9.2:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-192-table.png" alt="Ruby 1.9.2 on Linux and Windows" /&gt;&lt;/p&gt;
&lt;p&gt;JRuby:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-jruby-table.png" alt="JRuby on Linux and Windows" /&gt;&lt;/p&gt;
&lt;p&gt;Finally, in chart form (yellow entries are on Windows as indicated by the labels containing W):&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-plot.png" alt="Ruby on Linux Vs. Windows" /&gt;&lt;/p&gt;
&lt;p&gt;To use a beloved MythBusters expression, this myth is confirmed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: As requested by a few commenters, here is a comparison of IronRuby as well (.NET 4.0 Vs. Mono 2.4.4):&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/lin-win-ir-table.png" alt="Ruby 1.8.7 on Linux and Windows" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In conclusion, let me just state that it’s nice to see several implementations getting faster. Ruby 1.9.2, JRuby, MagLev and Rubinius are all becoming serious competitors and working their respective ways closer to a similar performance level. If you think these benchmark shootouts are becoming boring, then the results are becoming more stable and predictable. I suspect that as time goes on, performance will not be the real distinguishing factor when choosing a Ruby implementation, other features will be.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Agu4ePRDQsM:-UE-H366PU8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Agu4ePRDQsM:-UE-H366PU8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=Agu4ePRDQsM:-UE-H366PU8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Agu4ePRDQsM:-UE-H366PU8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=Agu4ePRDQsM:-UE-H366PU8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Agu4ePRDQsM:-UE-H366PU8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Agu4ePRDQsM:-UE-H366PU8:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Agu4ePRDQsM:-UE-H366PU8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=Agu4ePRDQsM:-UE-H366PU8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/Agu4ePRDQsM" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/#comments" thr:count="74" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/feed/atom/" thr:count="74" />
		<thr:total>74</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[In-Depth Book Review: Practical Clojure]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/lsUAZXR0350/" />
		<id>http://programmingzen.com/?p=1230</id>
		<updated>2010-07-20T04:22:38Z</updated>
		<published>2010-07-16T18:30:35Z</published>
		<category scheme="http://programmingzen.com" term="Books" /><category scheme="http://programmingzen.com" term="Clojure" /><category scheme="http://programmingzen.com" term="In-Depth Book Reviews" />		<summary type="html"><![CDATA[Title: Practical ClojureAuthors: Luke VanderHart and Stuart SierraTrue pp.: 198Publisher: ApressPublished on: June 2010ISBN-13: 978-1430272311Rating: 6.5/10 Published in June 2010, Practical Clojure by Luke VanderHart and Stuart Sierra is the latest Clojure book to hit stores. Despite the Clojure 1.0 jar shown at the beginning of the book, this title tries to cover the current [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/07/16/in-depth-book-review-practical-clojure/">&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?1430272317"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/07/41tKM6F53IL._SL160_.jpg" style="float: right; border:none;" alt="Practical Clojure" title="Practical Clojure" /&gt;&lt;/a&gt;&lt;br/&gt;Title: &lt;a href="http://programmingzen.com/recommends/?1430272317"&gt;&lt;strong&gt;Practical Clojure&lt;/strong&gt;&lt;/a&gt;&lt;br/&gt;Authors: &lt;strong&gt;Luke VanderHart and Stuart Sierra&lt;/strong&gt;&lt;br/&gt;True pp.: &lt;strong&gt;198&lt;/strong&gt;&lt;br/&gt;Publisher: &lt;strong&gt;Apress&lt;/strong&gt;&lt;br/&gt;Published on: &lt;strong&gt;June 2010&lt;/strong&gt;&lt;br/&gt;ISBN-13: &lt;a href="http://programmingzen.com/recommends/?1430272317"&gt;&lt;strong&gt;978-1430272311&lt;/strong&gt;&lt;/a&gt;&lt;br/&gt;Rating: &lt;strong&gt;6.5/10&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;br /&gt;
Published in June 2010, &lt;a href="http://programmingzen.com/recommends/?1430272317"&gt;Practical Clojure&lt;/a&gt; by Luke VanderHart and Stuart Sierra is the latest Clojure book to hit stores. Despite the Clojure 1.0 jar shown at the beginning of the book, this title tries to cover the current version of the language, including references to concepts that will be introduced by the upcoming 1.2 version.&lt;/p&gt;
&lt;p&gt;The target audience of this book is programmers who are absolutely new to Clojure. It didn&amp;#8217;t strike me as being particularly aimed at developers who are coming from the Java camp, or the Lisp camp; in this regard, the book is rather &amp;#8220;background agnostic&amp;#8221;, even though Lisp programmers will feel much more at home than Java programmers will, due to the nature of the language itself.&lt;/p&gt;
&lt;p&gt;The authors of the book are clearly well versed in this new language (Sierra is part of &lt;a href="http://clojure.com/"&gt;Clo&lt;em&gt;j&lt;/em&gt;ure/core&lt;/a&gt;, the equivalent of the A-Team in Clojureland) and their confidence with the concepts presented is demonstrated throughout the book. Their explanations tend to be clear and to the point. Longer discussions are occasionally included when required to introduce concepts that are novel to most programmers, like the Software Transactional Memory (STM), refs, atoms and agents.&lt;/p&gt;
&lt;p&gt;The book starts out by presenting a short but well-argued case for why Clojure is a worthwhile language, and then focuses almost exclusively on the core of the language. I&amp;#8217;m afraid they do so to the detriment of the ecosystem surrounding Clojure. The authors don&amp;#8217;t talk about how to install Clojure, recommend editors and IDEs (albeit a few are casually mentioned), or how to use build tools like Ant, Maven or Leiningen.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;clojure.contrib&lt;/code&gt;, a fundamental extension library, is barely mentioned and there is no coverage of other important libraries or emerging frameworks. For instance, perhaps expectedly, Compojure (a web framework) and Incanter (a statistical and graphical environment) are only mentioned as examples of DSLs, however examples of their usage are not provided. (I believe the authors mistakenly refer to Compojure as Enclojure, which is a different project).&lt;/p&gt;
&lt;p&gt;Despite the narrow focus, Practical Clojure doesn&amp;#8217;t shy away from complex subjects and manages to include a chapter on Java interoperability, parallel programming, metaprogramming, and performance considerations. It does so briefly however, favoring a cursory presentation of the fundamental concepts rather than in-depth coverage, which would provide the reader with the degree of confidence required to approach real world problems.&lt;/p&gt;
&lt;p&gt;The core language is covered in a manner that acts as both a tutorial and a reference. Major concepts, data structures, and common functions are presented to the reader with an endless supply of tiny examples. It&amp;#8217;s easy to fly through them, but typing along in the REPL will be a far more valuable exercise for readers who hope to retain the information presented.&lt;/p&gt;
&lt;p&gt;This leads us to another shortcoming of this book, which is the lack of more structured and complex examples. When I define their examples as &amp;#8220;tiny&amp;#8221;, with very few exceptions, I really mean it. For the first few chapters of the book the examples don&amp;#8217;t get much larger than calculating the square root of a number through Newton&amp;#8217;s method or adding contacts to an address book. Most of the other examples do a good job of illustrating the point they are trying to make with one, two, or just a handful of lines of code.&lt;/p&gt;
&lt;p&gt;This is an actual sample of the kind of examples you&amp;#8217;ll find throughout the book to illustrate many core API functions:&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="nv"&gt;user=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;reduce &lt;/span&gt;&lt;span class="nv"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="mi"&gt;15&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that this approach is didactically valid, because it isolates the function to show exactly how it works. After dozens of these functions though, you may expect larger examples to show how to integrate the use of some of these functions and data structures you&amp;#8217;ve learned about. Such examples are seldom included. Furthermore, the book lacks any exercise for the reader. Foundational books that fail to offer many articulated examples and that lack exercises, tend to make it hard for the reader to retain the information and get some hands-on practice.&lt;/p&gt;
&lt;p&gt;I have lots of respect for short books that get to the point and avoid wasting the reader&amp;#8217;s time. &lt;a href="http://programmingzen.com/recommends/?0131103628"&gt;K&amp;amp;R&lt;/a&gt; is notoriously acclaimed thanks to its clear and concise nature. However, Clojure is not C, and I feel that the 198 pages fall a little short when it comes to introducing this wonderful language to new readers. There is more to Clojure than simply surveying the language itself, even though I suspect that certain readers may appreciate this extremely narrow focus.&lt;/p&gt;
&lt;p&gt;Overall the book is well-edited, despite the presence of minor issues. Aside from a few typos (e.g., &amp;#8220;becauseall&amp;#8221; on page 79), readers may find the formatting to be slightly inconsistent at times. For example in chapter 5 when presenting sequences, after the &lt;code&gt;map&lt;/code&gt; function has been introduced, the font for the subsequent functions is substantially decreased for no apparent reason. Readers may be misled into thinking that the functions presented afterwards are somehow different from the previous ones, when in fact they&amp;#8217;re all defined in &lt;code&gt;clojure.core&lt;/code&gt;. In Listing 6-3, at page 103, the authors present their first &amp;#8220;complex&amp;#8221; example (the address book) and they do so by using, among others, &lt;code&gt;doseq&lt;/code&gt;. This macro was not introduced before that page nor is it really explained within the example.&lt;/p&gt;
&lt;p&gt;From a physical standpoint, this book is a rather thin and wide paperback. A small font, coupled with small margins and a wide layout, imply that the readability of the book suffers a little. The paper itself is off-white, fairly thick and slightly textured, not as pleasant to the touch as other books by Apress or most other technical publishers, even though I recognize that this is a matter of taste (some people may actually love it because of these characteristics).&lt;/p&gt;
&lt;p&gt;With two introductory Clojure books on the market, drawing comparisons is unavoidable. Stuart Halloway&amp;#8217;s &lt;a href="http://programmingzen.com/recommends/?1934356336"&gt;Programming Clojure&lt;/a&gt; is a slightly older book (published in May 2009), which grants Practical Clojure a distinct advantage. This is not to say that Programming Clojure is obsolete, on the contrary it&amp;#8217;s still a valid choice, but it doesn&amp;#8217;t illustrate some of the new features that are available today. For example, in chapter 13 Practical Clojure introduces protocols and datatypes that will be available in Clojure 1.2 for the first time. Given that Halloway&amp;#8217;s book was published more than a year ago, there was no possible way he could have included such powerful abstractions at the time.&lt;/p&gt;
&lt;p&gt;Despite being older and less methodical than Practical Clojure, Programming Clojure tends to offer more complex examples. In the introduction of Programming Clojure you&amp;#8217;ll see examples which Practical Clojure fails to include until much later in the book. Practical Clojure, the subject of this review, may leave you wanting for more practical examples of how all the language features fit together. Whereas Programming Clojure may leave you longing for more consistent explanations of how each part of the language works on its own.&lt;/p&gt;
&lt;p&gt;Practical Clojure and Programming Clojure are competitors in the marketplace, but it wouldn&amp;#8217;t be a bad idea to get ahold of both, because they complement each other quite well, in my opinion. Having to pick just one, I would probably recommend Practical Clojure, given its more consistent and up to date presentation. The sizzle offered by Programming Clojure, can be found to a much greater degree in upcoming and less introductory books, such as The Joy of Clojure. In this sense, reading Practical Clojure first followed by &lt;a href="http://affiliate.manning.com/idevaffiliate.php?id=980&amp;#038;url=4"&gt;The Joy of Clojure&lt;/a&gt;, would be a solid learning path (&lt;a href="http://affiliate.manning.com/idevaffiliate.php?id=980&amp;#038;url=5"&gt;Clojure in Action&lt;/a&gt; is another worthy addition, but it doesn&amp;#8217;t replace The Joy of Clojure, which is a real gem).&lt;/p&gt;
&lt;p&gt;In conclusion, Practical Clojure is not the Clojure equivalent of the highly praised &lt;a href="http://programmingzen.com/recommends/?1590592395"&gt;Practical Common Lisp&lt;/a&gt;, from the same publisher. Reading it cover to cover and typing all the snippets included within, will not give you enough knowledge to start writing complex, idiomatic Clojure programs out of the gate.&lt;/p&gt;
&lt;p&gt;However, if you are learning Clojure today, I do recommend this book. It&amp;#8217;s a clear, well thought-out, concise introduction to the language that will give you a solid foundation as you go on to learn more about Clojure and Lisp in general.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=lsUAZXR0350:UWUctdBfIl8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=lsUAZXR0350:UWUctdBfIl8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=lsUAZXR0350:UWUctdBfIl8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=lsUAZXR0350:UWUctdBfIl8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=lsUAZXR0350:UWUctdBfIl8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=lsUAZXR0350:UWUctdBfIl8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=lsUAZXR0350:UWUctdBfIl8:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=lsUAZXR0350:UWUctdBfIl8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=lsUAZXR0350:UWUctdBfIl8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/lsUAZXR0350" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/07/16/in-depth-book-review-practical-clojure/#comments" thr:count="12" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/07/16/in-depth-book-review-practical-clojure/feed/atom/" thr:count="12" />
		<thr:total>12</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/07/16/in-depth-book-review-practical-clojure/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[How to setup Clojure from scratch]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/qWacb49zy0g/" />
		<id>http://programmingzen.com/?p=1227</id>
		<updated>2010-07-13T21:11:49Z</updated>
		<published>2010-07-13T18:46:34Z</published>
		<category scheme="http://programmingzen.com" term="Clojure" /><category scheme="http://programmingzen.com" term="Programming Languages" />		<summary type="html"><![CDATA[My previous post about Clojure generated quite a bit of interest, so I thought I&#8217;d follow it up with something a bit more concrete. I primarily wrote this article for a friend who asked me for guidance on how to set it all up; and while this isn&#8217;t he only way to setup Clojure, I [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/07/13/how-to-setup-clojure-from-scratch/">&lt;p&gt;My previous &lt;a href="http://programmingzen.com/2010/07/09/thoughts-on-clojure/"&gt;post about Clojure&lt;/a&gt; generated quite a bit of interest, so I thought I&amp;#8217;d follow it up with something a bit more concrete. I primarily wrote this article for a friend who asked me for guidance on how to set it all up; and while this isn&amp;#8217;t he only way to setup Clojure, I hope it will help other people who are also getting started with this great  language.&lt;/p&gt;
&lt;p&gt;As some people pointed out, setting up your Clojure environment can be slightly challenging. For example, when you install Ruby or Python, you can expect a Read-Eval-Print Loop (REPL) such as IRB or IDLE to be ready for you to use right out of the box, whereas the current version of Clojure (version 1.1) does not include an interactive top-level.&lt;/p&gt;
&lt;p&gt;This post explains how to setup a Clojure environment step-by-step, including a working &lt;code&gt;clj&lt;/code&gt; script (the common name for Clojure&amp;#8217;s REPL). For this post I used the &lt;code&gt;clj&lt;/code&gt; script contained within the &lt;a href="http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started"&gt;Getting Started&lt;/a&gt; guide on Wikibooks as a base, but I built on top of it , so as to customize and improve it. In writing this post, I’ve made the assumption that you’re using a *nix environment. My instructions will be Mac OS X specific, even though it should be a breeze to adapt them for Linux, if required.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Download and Build Clojure&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The first step is to download and build the latest version of Clojure. (Please note, I used bit.ly below for code formatting reasons.)&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp
&lt;span class="nv"&gt;$ &lt;/span&gt;wget http://bit.ly/clojure
&lt;span class="nv"&gt;$ &lt;/span&gt;unzip clojure-1.1.0.zip
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;clojure-1.1.0
&lt;span class="nv"&gt;$ &lt;/span&gt;ant
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will generate several jars for us, including &lt;code&gt;clojure.jar&lt;/code&gt;, which we’re interested in. Aside from clojure.core, we are also interested in clojure.contrib, a collection of useful libraries and functions that are often used in Clojure programs. To download and build clojure.contrib, follow these instructions:&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp
&lt;span class="nv"&gt;$ &lt;/span&gt;wget http://bit.ly/clojure-contrib
&lt;span class="nv"&gt;$ &lt;/span&gt;unzip clojure-contrib-1.1.0.zip
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;clojure-contrib-1.1.0
&lt;span class="nv"&gt;$ &lt;/span&gt;ant
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This should generate a &lt;code&gt;clojure-contrib.jar&lt;/code&gt; file. We can now proceed to copy both the &lt;code&gt;clojure.jar&lt;/code&gt; and &lt;code&gt;clojure-contrib.jar&lt;/code&gt; files to a convenient location. (You can copy the files with a single line, but for formatting reasons I split the operation into two copy operations).&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mkdir -p ~/Library/Clojure/lib
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/Library/Clojure/lib
&lt;span class="nv"&gt;$ &lt;/span&gt;cp /tmp/clojure-1.1.0/clojure.jar .
&lt;span class="nv"&gt;$ &lt;/span&gt;cp /tmp/clojure-contrib-1.1.0/clojure-contrib.jar .
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that on Linux, you&amp;#8217;d choose a different location (e.g., &lt;code&gt;/opt/clojure/lib&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Install rlwrap&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Before we can proceed with creating a fancy &lt;code&gt;clj&lt;/code&gt; script, we need &lt;code&gt;rlwrap&lt;/code&gt;, which will make our interactive prompt much more friendly. On Mac OS X, if you are using MacPorts, you can simply run the following:&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;sudo port install rlwrap
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Create a clj script&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now we can finally finally create a &lt;code&gt;clj&lt;/code&gt; script and save it as &lt;code&gt;~/Library/Clojure/clj&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nv"&gt;breakchars&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;(){}[],^%$#@\&amp;quot;\&amp;quot;;:&amp;#39;&amp;#39;|\\&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;CLOJURE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/Library/Clojure/lib
&lt;span class="nv"&gt;CLOJURE_JAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$CLOJURE_DIR&lt;/span&gt;/clojure.jar
&lt;span class="nv"&gt;CONTRIB_JAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$CLOJURE_DIR&lt;/span&gt;/clojure-contrib.jar
&lt;span class="nv"&gt;CLOJURE_CP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$CLOJURE_JAR&lt;/span&gt;:&lt;span class="nv"&gt;$CONTRIB_JAR&lt;/span&gt;:&lt;span class="nv"&gt;$PWD&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -f .clojure &lt;span class="o"&gt;]&lt;/span&gt;; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;	&lt;/span&gt;&lt;span class="nv"&gt;CLOJURE_CP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$CLOJURE_CP&lt;/span&gt;:&lt;span class="sb"&gt;`&lt;/span&gt;cat .clojure&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$# &lt;/span&gt;-eq 0 &lt;span class="o"&gt;]&lt;/span&gt;; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;	&lt;/span&gt;&lt;span class="nb"&gt;exec &lt;/span&gt;rlwrap --remember -c -b &lt;span class="nv"&gt;$breakchars&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                -f &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.clj_completions &lt;span class="se"&gt;\&lt;/span&gt;
                java -cp &lt;span class="nv"&gt;$CLOJURE_CP&lt;/span&gt; clojure.main -i &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.clojure.clj --repl
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="k"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;exec &lt;/span&gt;java -cp &lt;span class="nv"&gt;$CLOJURE_CP&lt;/span&gt; clojure.main -i &lt;span class="nv"&gt;$HOME&lt;/span&gt;/.clojure.clj &lt;span class="nv"&gt;$1&lt;/span&gt; -- &lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Make it executable and symlink it to a convenient place on your path (e.g., &lt;code&gt;~/bin&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;chmod a+x ~/Library/Clojure/clj
&lt;span class="nv"&gt;$ &lt;/span&gt;ln -s ~/Library/Clojure/clj ~/bin/.
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;At this point we almost have a working script. Before declaring it fully functional, let&amp;#8217;s take a look at three files this script references:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.clojure&lt;/code&gt;&lt;/strong&gt;: This file is optional and is located in the same folder as the scripts you want to execute. It can be used to include further jars in your classpath.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;~/.clj_completions&lt;/code&gt;&lt;/strong&gt;: Includes a list of Clojure functions for tab completion (courtesy of rlwrap).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;~/.clojure.clj&lt;/code&gt;&lt;/strong&gt;: Your Clojure startup file. It&amp;#8217;s the first Clojure file that&amp;#8217;s run when we start the REPL or execute a script. We&amp;#8217;ll use this to add a couple of nice functions to the default &lt;code&gt;clj&lt;/code&gt; REPL, but you can add anything you&amp;#8217;d like to load at startup.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 4: Create a startup file&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By default, &lt;code&gt;clj&lt;/code&gt; will not have an &lt;code&gt;exit&lt;/code&gt; function. You can either CTRL+D or enter a call to &lt;code&gt;System/exit&lt;/code&gt;. This is not a big deal, but I like the idea of exiting with a simple &lt;code&gt;(exit)&lt;/code&gt; call (as one does with Ruby and Python). Fortunately, we can add this function to the startup file. Furthermore, for learning purposes, few things beat having the &lt;code&gt;source&lt;/code&gt; function which reveals the source code of built-in Clojure functions. This too can be added to &lt;code&gt;~/.clojure.clj&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;clojure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;contrib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;repl-utils&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;exit&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;System/exit&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;(exit)&lt;/code&gt; will now exit the REPL and &lt;code&gt;source&lt;/code&gt; will reveal the source code as shown below:&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="nv"&gt;user=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;source&lt;/span&gt; &lt;span class="nv"&gt;peek&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;peek&lt;/span&gt;
  &lt;span class="s"&gt;&amp;quot;For a list or queue, same as first, for a vector, same as, but much&lt;/span&gt;
&lt;span class="s"&gt;  more efficient than, last. If the collection is empty, returns nil.&amp;quot;&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;clojure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;RT&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;peek &lt;/span&gt;&lt;span class="nv"&gt;coll&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="nv"&gt;nil&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Step 5: Create a ~/.clj_completions file&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As explained in the Clojure Wikibook referenced above, you can create the &lt;code&gt;.clj_completions&lt;/code&gt; file by running the following from the REPL or as a script (e.g., &lt;code&gt;clj myscript.clj&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;def &lt;/span&gt;&lt;span class="nv"&gt;completions&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;reduce &lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;keys &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ns-publics &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;find-ns &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
                        &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;clojure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;core&lt;/span&gt; &lt;span class="nv"&gt;clojure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;clojure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;xml&lt;/span&gt; &lt;span class="nv"&gt;clojure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;with-open &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;BufferedWriter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;FileWriter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;System/getenv&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;HOME&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/.clj_completions&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))]&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;write&lt;/span&gt; &lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply &lt;/span&gt;&lt;span class="nv"&gt;str&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;interleave &lt;/span&gt;&lt;span class="nv"&gt;completions&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;repeat &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will populate the file &lt;code&gt;.clj_completions&lt;/code&gt; with a list of 500+ symbols. You can now run &lt;code&gt;clj&lt;/code&gt; and try tab completion by inserting a few characters and then pressing tab. For example: &lt;/p&gt;
&lt;div class="highlight"&gt;
&lt;pre&gt;&lt;span class="nv"&gt;mbp:~&lt;/span&gt; &lt;span class="nv"&gt;acangiano$&lt;/span&gt; &lt;span class="nv"&gt;clj&lt;/span&gt;
&lt;span class="nv"&gt;Clojure&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nv"&gt;user=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;re&lt;/span&gt;&lt;span class="c1"&gt;&amp;lt;tab&amp;gt;&lt;/span&gt;
&lt;span class="nv"&gt;re-find&lt;/span&gt;                &lt;span class="nv"&gt;ref-min-history&lt;/span&gt;        &lt;span class="nv"&gt;repeatedly&lt;/span&gt;
&lt;span class="nv"&gt;re-groups&lt;/span&gt;              &lt;span class="nv"&gt;ref-set&lt;/span&gt;                &lt;span class="nv"&gt;replace&lt;/span&gt;
&lt;span class="nv"&gt;re-matcher&lt;/span&gt;             &lt;span class="nv"&gt;refer&lt;/span&gt;                  &lt;span class="nv"&gt;replicate&lt;/span&gt;
&lt;span class="nv"&gt;re-matches&lt;/span&gt;             &lt;span class="nv"&gt;refer-clojure&lt;/span&gt;          &lt;span class="nv"&gt;require&lt;/span&gt;
&lt;span class="nv"&gt;re-pattern&lt;/span&gt;             &lt;span class="nv"&gt;release-pending-sends&lt;/span&gt;  &lt;span class="nv"&gt;reset!&lt;/span&gt;
&lt;span class="nv"&gt;re-seq&lt;/span&gt;                 &lt;span class="nv"&gt;rem&lt;/span&gt;                    &lt;span class="nv"&gt;reset-meta!&lt;/span&gt;
&lt;span class="nv"&gt;read&lt;/span&gt;                   &lt;span class="nv"&gt;remove&lt;/span&gt;                 &lt;span class="nv"&gt;resolve&lt;/span&gt;
&lt;span class="nv"&gt;read-line&lt;/span&gt;              &lt;span class="nv"&gt;remove-method&lt;/span&gt;          &lt;span class="nv"&gt;rest&lt;/span&gt;
&lt;span class="nv"&gt;read-string&lt;/span&gt;            &lt;span class="nv"&gt;remove-ns&lt;/span&gt;              &lt;span class="nv"&gt;resultset-seq&lt;/span&gt;
&lt;span class="nv"&gt;reduce&lt;/span&gt;                 &lt;span class="nv"&gt;remove-watch&lt;/span&gt;           &lt;span class="nv"&gt;reverse&lt;/span&gt;
&lt;span class="nv"&gt;ref&lt;/span&gt;                    &lt;span class="nv"&gt;rename&lt;/span&gt;                 &lt;span class="nv"&gt;reversible?&lt;/span&gt;
&lt;span class="nv"&gt;ref-history-count&lt;/span&gt;      &lt;span class="nv"&gt;rename-keys&lt;/span&gt;
&lt;span class="nv"&gt;ref-max-history&lt;/span&gt;        &lt;span class="nv"&gt;repeat&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There you have it, a complete setup of Clojure from source to &lt;code&gt;clj&lt;/code&gt;. You can find information about setting up your favorite editor/IDE on the &lt;a href="http://www.assembla.com/wiki/show/clojure/Getting_Started"&gt;Assembla Wiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As pointed out by Phil and other commenters elsewhere, the easiest way to get started these days is probably to install &lt;a href="http://github.com/liebke/cljr"&gt;cljr&lt;/a&gt;, a standalone REPL and package manager. My post outlines how to do it from scratch (as you can deduct from the title), just like we used to before these tools were released. You may however consider the pre-packaged solution instead.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=qWacb49zy0g:kqTP3qnbJcE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=qWacb49zy0g:kqTP3qnbJcE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=qWacb49zy0g:kqTP3qnbJcE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=qWacb49zy0g:kqTP3qnbJcE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=qWacb49zy0g:kqTP3qnbJcE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=qWacb49zy0g:kqTP3qnbJcE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=qWacb49zy0g:kqTP3qnbJcE:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=qWacb49zy0g:kqTP3qnbJcE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=qWacb49zy0g:kqTP3qnbJcE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/qWacb49zy0g" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/07/13/how-to-setup-clojure-from-scratch/#comments" thr:count="12" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/07/13/how-to-setup-clojure-from-scratch/feed/atom/" thr:count="12" />
		<thr:total>12</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/07/13/how-to-setup-clojure-from-scratch/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[Thoughts on Clojure]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/XlfL2FrZU1Y/" />
		<id>http://programmingzen.com/?p=1225</id>
		<updated>2010-07-09T20:28:02Z</updated>
		<published>2010-07-09T18:00:32Z</published>
		<category scheme="http://programmingzen.com" term="Clojure" /><category scheme="http://programmingzen.com" term="Python" /><category scheme="http://programmingzen.com" term="Ruby" />		<summary type="html"><![CDATA[Lisp has had a tremendous impact on the world of programming. Even though Common Lisp and Scheme &#8212; the two main Lisp dialects &#8212; may not be considered mainstream today, several popular languages have been influenced by one or both of them. It isn&#8217;t stretching things too much to say that both Ruby and Python [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/07/09/thoughts-on-clojure/">&lt;p&gt;Lisp has had a tremendous impact on the world of programming. Even though Common Lisp and Scheme &amp;mdash; the two main Lisp dialects &amp;mdash; may not be considered mainstream today, several popular languages have been influenced by one or both of them.&lt;/p&gt;
&lt;p&gt;It isn&amp;#8217;t stretching things too much to say that both Ruby and Python can be seen as slower, easier (for beginners), object-oriented, infix Lisp dialects.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Some may say Ruby is a bad rip-off of Lisp or Smalltalk, and I admit that. But it is nicer to ordinary people. &amp;mdash; Yukihiro &amp;#8220;Matz&amp;#8221; Matsumoto&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Ruby and Python aren&amp;#8217;t intimidating and remain very approachable for absolute beginners. Furthermore, their approachability is not confined to the language design itself, but transcends into the community and ecosystem that surrounds them.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not here to discuss how languages like Ruby and Python managed to become more popular than major Lisp dialects nowadays. I&amp;#8217;d rather focus on how these gentler introductions to functional programming are acting as gateway drugs to Lisp for many developers.&lt;/p&gt;
&lt;p&gt;A community that values metaprogramming and is obsessed with the construction of DSLs (Domain Specific Languages) like the Ruby&amp;#8217;s is, will no doubt find in Lisp a valuable ally. Plus, if you know Ruby inside and out, you should find Lisp to be easy enough to learn.&lt;/p&gt;
&lt;p&gt;To attract Ruby developers though, Lisp has to offer something more than just a set of powerful features. You could say that Rails is enough of a reason to learn and use Ruby. But what is Lisp able to solve all that better than Ruby? I&amp;#8217;ll answer that question by focusing on a specific dialect of Lisp, that I and continually more Ruby developers are getting into: &lt;a href="http://clojure.org"&gt;Clojure&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It wouldn&amp;#8217;t be fair to characterize the Lisp community as stagnant, but Clojure is definitely a welcomed dose of new blood. Clojure is a JVM-based modern Lisp designed for concurrency, which elegantly includes a set of carefully chosen features that are not easily found in mainstream languages.&lt;/p&gt;
&lt;p&gt;In my opinion, Clojure has three main advantages over Ruby:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;#8217;s much faster than Ruby, which makes it a better choice for intensive processing. (&lt;a href="http://www.infoq.com/articles/flightcaster-clojure-rails"&gt;FlightCaster&lt;/a&gt; for example, uses both Rails and Clojure. Rails for the &amp;#8220;front-end&amp;#8221; and Clojure for the heavy lifting/forecasting.)&lt;/li&gt;
&lt;li&gt;It greatly simplifies concurrent programming, making the language more future-proof as hardware manufacturers continue to produce processors with more CPU cores.&lt;/li&gt;
&lt;li&gt;Clojure emphasizes functional programming and tries to minimize side effects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clojure&amp;#8217;s interoperability with Java resolves the issue of only having a few available libraries, which often affects new languages. It also helps in getting people to use the language within the enterprise world where Java still dominates.&lt;/p&gt;
&lt;p&gt;Of all the &amp;#8220;new&amp;#8221; languages out there, I find Clojure to be the most fun, interesting and pragmatic: it&amp;#8217;s something worth getting excited about. I don&amp;#8217;t really care if it turns out to be the next Ruby or not, it&amp;#8217;s a language that&amp;#8217;s worth knowing and using. (If you haven&amp;#8217;t tried it yet, a decent, short introductory book is the recently published &lt;a href="http://programmingzen.com/recommends/?1430272317"&gt;Practical Clojure&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Clojure&amp;#8217;s popularity may even bring more attention to Lisp in general (for example, most &lt;a href="http://programmingzen.com/recommends/?0262011530"&gt;must-read&lt;/a&gt; literature uses Scheme or Common Lisp). Perhaps then, it may indirectly help introduce more traditional Lisp dialects to a new generation of programmers.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=XlfL2FrZU1Y:DEEWaVtjKzM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=XlfL2FrZU1Y:DEEWaVtjKzM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=XlfL2FrZU1Y:DEEWaVtjKzM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=XlfL2FrZU1Y:DEEWaVtjKzM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=XlfL2FrZU1Y:DEEWaVtjKzM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=XlfL2FrZU1Y:DEEWaVtjKzM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=XlfL2FrZU1Y:DEEWaVtjKzM:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=XlfL2FrZU1Y:DEEWaVtjKzM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=XlfL2FrZU1Y:DEEWaVtjKzM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/XlfL2FrZU1Y" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/07/09/thoughts-on-clojure/#comments" thr:count="8" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/07/09/thoughts-on-clojure/feed/atom/" thr:count="8" />
		<thr:total>8</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/07/09/thoughts-on-clojure/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[The pursuit of excellence in programming]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/rmbcXmVN3Jo/" />
		<id>http://programmingzen.com/?p=1224</id>
		<updated>2010-07-15T00:12:05Z</updated>
		<published>2010-07-04T22:59:44Z</published>
		<category scheme="http://programmingzen.com" term="General" /><category scheme="http://programmingzen.com" term="Programming Languages" /><category scheme="http://programmingzen.com" term="Web Development" />		<summary type="html"><![CDATA[As I write a series of thoughts on the pursuit of excellence in programming, I must preface my essay by asking you to ignore that I wrote these words. I invite you to evaluate the opinions and ideas presented here not ad hominem, but rather on the basis of their own merits. It would be [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/07/04/the-pursuit-of-excellence-in-programming/">&lt;p&gt;As I write a series of thoughts on the pursuit of excellence in programming, I must preface my essay by asking you to ignore that I wrote these words. I invite you to evaluate the opinions and ideas presented here not &lt;em&gt;ad hominem&lt;/em&gt;, but rather on the basis of their own merits. It would be easy to otherwise mistakenly dismiss them with the infamous question posed by Steve Jobs to a blogger: “What have you done that’s so great?”.&lt;/p&gt;
&lt;p&gt;This is to say that I talk about the ambitious and noble goal of achieving excellence in programming, fully conscious of not having achieved said excellence. For the time being, I don’t feel like I can point my finger at something that would impress Steve Jobs (or less critical observers). I’m just a traveler on the journey of learning, with a desire to share his experiences and plans.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Two visions of intelligence&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Mastering a complex discipline such as programming requires a great amount of learning over the course of several years, perhaps even decades. Maximizing one’s ability to learn is therefore an early investment that can quickly repay itself.&lt;/p&gt;
&lt;p&gt;The biggest impact on my ability to learn was caused by a shift in the way I considered the matter of intelligence. There are mainly two ways to think about it. You can either consider intelligence to be a static, intrinsic ability or a more dynamic, cultivable characteristic of human beings.&lt;/p&gt;
&lt;p&gt;Cognitive scientists and psychologists conclusively determined that people who perceived intelligence as a dynamic characteristic, outperformed and were more successful than people who internalized intelligence as an intrinsic, static ability.&lt;/p&gt;
&lt;p&gt;It’s worth noting that it’s not really important whether intelligence can actually be developed through application. It’s the perception of it that forges students’ approach to learning.&lt;/p&gt;
&lt;p&gt;This difference in perception is often conditioned by early parenting. Kids who are encouraged to work hard to achieve results and are praised on the basis of their effort, tend to develop a perception of intelligence and results as something they can work on. Other kids are conditioned to think that they are doing well because they are “smart” and that their intelligence alone will most likely lead them to success.&lt;/p&gt;
&lt;p&gt;Society has a fascination with genius, and parents like to fancy their little ones to be several standard deviations better than the norm, but conditioning children this way has dangerous and counterproductive consequences.&lt;/p&gt;
&lt;p&gt;Kids who are labeled and praised because of their “innate capabilities”, will often suffer from an overconfidence that will affect their ability to challenge themselves through the depths of the unknown, because they feel it would threaten their status. What if they fail? It would mean, in their eyes, that perhaps they are not the smart person they have been assumed to be all along. We all have seen such kids failing here and there, and quickly making excuses such as, “Oh, I wasn’t trying at all”.&lt;/p&gt;
&lt;p&gt;A parent who is cultivating a kid’s interest in hard work, may be more likely to encourage their child with words such as, “It’s OK. Keep studying, and you’ll definitely do better next time”. A parent proposing a model of static intelligence, may justify their child’s failure in a given subject by concluding that “maybe you are not cut out for subject X”. [1]&lt;/p&gt;
&lt;p&gt;When facing failure, the “static intelligence” child may crumble under the weight of his own demise, as if failure was a reflection of their intrinsic value rather than a temporary speed bump and occasion for growth. A “dynamic intelligence” child will simply try harder next time. Genius or not, excellence and mastery of any subject requires hard work and many “smart” kids fall short when the bar is raised high enough so that “smartness” alone won’t cut it anymore. This usually corresponds with the switch from high school to college.&lt;/p&gt;
&lt;p&gt;I’m very familiar with all of this, because I was one of those kids. I was labeled by my parents and science teachers as a “genius”. Even psychologists at school, who came to help us figure out what careers we were better suited for, ended up telling me that I could pursue virtually any career (at the time I was interested in nuclear physics) and that according to their (virtually meaningless) IQ tests I would be classified as a &amp;#8220;genius&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Please note that the problem wasn’t so much the label. Most smart kids figure out that they are smart on their own rather quickly. The real problem was that I wasn’t taught the value of long-term intellectual effort. Effort itself was considered as being somewhat detrimental to my status. Not only was I supposed to succeed, but I supposedly had to do so without putting forth any effort (a &amp;#8220;utopic&amp;#8221; ambition).&lt;/p&gt;
&lt;p&gt;One of the first example of this that I can remember is when my father “caught me studying” for a few hours the same book before a test in middle school. He told me something along the lines of “Why do you need to study? A genius like you should figure out the test without studying.”. It’s absurd, I know, and probably one of the dumbest things my &amp;mdash; otherwise bright &amp;mdash; father has ever told me. As a young kid though, such a statement can have a strong impact on you.&lt;/p&gt;
&lt;p&gt;Another example has to do with Latin. My teacher was a palm reading, crazy cat lady and I had no respect for her from the start. So I didn’t pay attention in class, on top of not studying Latin at home, I set myself up for failure. When the first translation assignment came around, I got a mildly negative score. My less than professional teacher told me, “Oh I thought you were good, but I guess you are not”. Afterwards my father added to this by saying something along the lines of, “Well, don’t worry, I guess languages are not your strength.”.&lt;/p&gt;
&lt;p&gt;Boom. That was enough for me to stop having any interest in Latin and completely ignore a subject at which I wasn’t excelling. Nobody could tell me, “You are stupid because you don’t understand Latin,” if I didn’t try at all. So I was the high school kid who did advanced Calculus stuff on his own for fun, when my classmates where struggling with Algebra, yet I pretty much sucked at Latin. (In retrospective, the thought patterns required to excel at Latin where not very different from those required to excel at math or mastering English as a second language. I suspect that had I put in some effort I could have been very good at, and actually enjoyed, the subject.)   &lt;/p&gt;
&lt;p&gt;Over the years I had to readjust this perception entirely. By falling on my face more than once, I learned that excellence is only achieved through a combination of talent and effort. The real genius may lie in the ability to put in thousands of hours of focused study and practice, in the pursuit of whatever one person is trying to learn and understand.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;If people knew how hard I worked to get my mastery, it wouldn&amp;#8217;t seem so wonderful at all. &amp;mdash; Michelangelo&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;By this new definition, I was a complete idiot who had to entirely learn from scratch how to appreciate the value of effort to hone and develop his “talent” (which is nothing but a seed on its own).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Learning to learn&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Being very interested in programming, computer science, mathematics, and science in general, I decided at some point that I had to entirely change my attitude towards learning if I were to master any of those disciplines. Effort was now more important than intelligence on its own, and I would feel satisfied only when doing a really good job in the pursuit of something challenging, that couldn’t be achieved by sheer “talent”.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The saddest thing in life is wasted talent, and the choices that you make will shape your life forever. &amp;mdash; Calogero &amp;#8216;C&amp;#8217; Anello from A Bronx Tale&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;In the process, I started to internalize a few principles and I dealt with issues related to both the art of learning and the art of programming.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;An awful feeling&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There is a cognitive bias known as the Dunning-Kruger effect [2], in which subjects who are inexperienced or less competent within a given discipline, tend to overestimate their abilities (they are in other words affected by illusory superiority [3]).&lt;/p&gt;
&lt;p&gt;The other side of this coin is that the more you study, the more you realize how little you know and how much there is to know (a concept put forward by Socrates back in the days of Ancient Greece). This is both a pleasure and a discomfort. There is a huge amount of satisfaction in finding things out. Yet, being in doubt and fully aware of how little you know tends to be an unpleasant side effect all learners have to live with. Doubt truly is the water that’s fundamental for the growth of the flower of intellectual curiosity. [4]&lt;/p&gt;
&lt;p&gt;My approach in this case is to embrace and dominate my ignorance and fears. Whenever there is a concept that I feel particularly ignorant about or that is way over my head, I try to tackle it as if my life depended on it. There are still countless things I’m ignorant about, but this approach as really paid off for me over the years.&lt;/p&gt;
&lt;p&gt;If you are trying to learn a whole branch of computer science or mathematics, it will take a long time, so you may want to start first with smaller “fears” that can be mastered, at least at an introductory level, in a short amount of time. Rather than thinking, “Oh yeah, I should really learn Git”, for months, act on the thought. The essential knowledge to work with Git or Hg doesn’t take months to learn (assuming you have a need for either of these particular tools).&lt;/p&gt;
&lt;p&gt;But you are in this for the long run, so don’t be afraid of improving your craft by studying advanced topics that require a bigger commitment in terms of time as well. There is no royal shortcut, mastery of our craft will require thousands of hours of dedicated study and practice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Theory and practice&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Masters of any intellectual discipline tend to have good working knowledge of both theoretical and practical aspects. Pursuing excellence in programming requires the study of many insightful books that will widen your view of the field and as a result necessarily improve your craft.&lt;/p&gt;
&lt;p&gt;Working with books alone is not enough though. Programming requires writing and reading programs every day for years. That’s why I have a rule: I refuse to go to sleep if I haven’t read and written some code on a given day (this doesn’t include the code I write for work, of course). So far, this rule has had a positive impact on my ability to code.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;It is a mistake to think that the practice of my art has become easy to me. I assure you, dear friend, no one has given so much care to the study of composition as I. There is scarcely a famous master in music whose works I have not frequently and diligently studied. &amp;mdash; Mozart&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Breadth Vs. Depth&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As we progress in our journey towards the pursuit of excellence in programming, a question that will no doubt pester people’s minds is whether one should go for breadth of knowledge, or depth. There are countless programming languages, paradigms, methodologies, technologies, et cetera.&lt;/p&gt;
&lt;p&gt;The truth of the matter is that if we are to become GrandMaster programmers, we cannot ignore either of them. In practice, depth has a much stronger impact in the way we construct software. It is through deep understanding that we can see the whole through the parts. There is therefore value in specializing in just a few languages and technologies, and really mastering them in-depth.&lt;/p&gt;
&lt;p&gt;Getting things done in software development requires a certain pragmatism and proficiency with the tools at hand. There is no escaping it. Depth is therefore necessary, but not sufficient.&lt;/p&gt;
&lt;p&gt;I find that the web is particularly good at covering the breadth aspect of things. There are always new and interesting areas I can learn about and experiment with. I don’t need a whole 600 page book to get a feeling for &amp;mdash; or to better understand &amp;mdash; certain technologies that are not crucial to my area of specialization.&lt;/p&gt;
&lt;p&gt;While there are quite a few exceptions I could mention, I’d say that I tend to use the Internet as an aid for horizontal scaling of my knowledge, and books for vertical scaling. And again, more often than not, the depth level is mostly determined by the amount of time, practice and effort I put into it, rather than the media I’m using.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where to find time&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One of the objections I hear often, particularly when it comes to reading books is, “I don’t have time!”. In a few extreme cases, that may actually be true, but I think that most people severely underestimate how much time is “wasted” on a daily basis (even just surfing online).&lt;/p&gt;
&lt;p&gt;Breaks are extremely important, and I’m not advocating any regime of incessant study. I simply know how crucial it is to be constant. It’s a marathon, not a sprint.&lt;/p&gt;
&lt;p&gt;My second rule is: I refuse to got sleep if I haven’t read at least a chapter of a book that day. Very often I get caught up in the book I’m reading or working through, and end up getting through much more than just one chapter (it really depends on the book, of course). But for me the rule is clear: no sleep allowed until one chapter has been read every day.&lt;/p&gt;
&lt;p&gt;Try this approach and you’ll see that reading doesn’t have to take up much time, yet doing so you can still read several books (including technical ones) every month.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;We are what we repeatedly do. Excellence, then, is not an act but a habit. &amp;mdash; Aristotle&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;For certain books, it is convenient to have the book in PDF format on your computer, as you switch from the book to the editor/console and back. However, generally speaking the computer tends to be quite distracting and thoughts like “I’ll just check my email quickly” can easily lead to hours spent doing something else.&lt;/p&gt;
&lt;p&gt;For this reason I prefer to read from a paper book which is also easier on the eyes for extensive reading after a day in front of a computer screen. Even if I’m using the computer at the same time to input code, the physical presence of a book next to my laptop is enough to remind me that I shouldn’t get distracted online. (For me the depth and focus required by books is also an antidote to the re-wiring that the web tends to do to our brains. [5])&lt;/p&gt;
&lt;p&gt;By the way, a few days ago Amazon announced a gorgeous, brand new graphite color Kindle DX [6]. I think I may pull the trigger and get it for my upcoming 30th birthday. Buying numerous paper books is expensive, and given the price of Kindle books, this move would end up being cheaper in the long run. The large e-ink display almost looks like paper and the device is not as distracting as an iPad (you read on a Kindle, and that’s it). Plus, it’s lighter than most technical books and surely takes up less space in your home.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Achieving focus&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With so much going on within the programming world, distractions are easy to come by. My approach is to focus only on the given macro-task at hand. If I’m trying to learn about process calculi for example, then for the next few months my “learning time” will be ruthlessly dedicated to that subject, as if the rest of the programming ecosystem stopped in time.&lt;/p&gt;
&lt;p&gt;Then there is focusing at a micro-task level. Learning about a given subject can always be divided into a long series of smaller steps. When I’m focusing on one such, tiny step, then everything else ceases to exist (or at least in theory).&lt;/p&gt;
&lt;p&gt;One trick I use to achieve solemn focus on micro-tasks, whether reading code, writing code, or reading a technical book, is the use of the Pomodoro Technique [7]. In short, I use timer software [8] which alerts me when 25 minutes (a pomodoro) have passed, and gives me a 5 minute break for each pomodoro. Every 4 pomodoros, I can take a longer break.&lt;/p&gt;
&lt;p&gt;When I first started using this technique I thought it was mostly a gimmick and I had a hard time taking breaks. I just wanted to keep going and the “tracking” seemed silly. However, I must say that it strikes an elegant balance between the desire to focus for extensive periods of time and the importance of taking regular mini-breaks.&lt;/p&gt;
&lt;p&gt;This approach has become routine for my mind now, so even if it is just a gimmick, it’s still a good way for me to get focused and “in the zone”.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Aiming for sprezzatura&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The pursuit of excellence requires a huge drive from within, and a fundamental dissatisfaction with just being good at a given discipline. I believe this is true regardless of the profession at hand.&lt;/p&gt;
&lt;p&gt;As I progress in my journey, I’m discovering how the key is to make the pursuit of excellence a habit. This goes against my nature of being an intellect sprinter, but I’m in for the long run and I’m really learning to enjoy the, marathon like, process.&lt;/p&gt;
&lt;p&gt;My long-term goal is to program with sprezzatura [9], where the process is so internalized and part of my subconscious that it almost looks effortless (as if the act of programming was committed to muscle memory). It will be an overnight success, 15 years in the making.&lt;/p&gt;
&lt;p&gt;Regardless of the improvement level achieved, I will always have the joy, privilege and need to continue to learn for the betterment of myself and my craft. When there is no set destination, the journey is what really matters.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Ancora imparo. (I’m still learning.) &amp;mdash; Michelangelo&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;Notes&lt;/p&gt;
&lt;p&gt;[1] These concepts are explained, in a much more eloquent manner, in the early chapters of the excellent book, &lt;a href="http://programmingzen.com/recommends/?0743277465"&gt;The Art of Learning&lt;/a&gt; by Josh Waitzkin.&lt;/p&gt;
&lt;p&gt;[2] &lt;a href="http://en.wikipedia.org/wiki/Dunning-Kruger_effect"&gt;Dunning-Kruger Effect&lt;/a&gt; on Wikipedia.&lt;/p&gt;
&lt;p&gt;[3] &lt;a href="http://en.wikipedia.org/wiki/Illusory_superiority"&gt;Illusory Superiority&lt;/a&gt; on Wikipedia.&lt;/p&gt;
&lt;p&gt;[4] For more on the importance of doubt in science, check out the beautiful epilogue in &lt;a href="http://programmingzen.com/recommends/?0393320928"&gt;What do you care what other people think?&lt;/a&gt; by Richard P. Feynman.&lt;/p&gt;
&lt;p&gt;[5] For more on this phenomenon, read &lt;a href="http://programmingzen.com/recommends/?0393072223"&gt;The Shallows&lt;/a&gt; by Nicholas Carr. &lt;/p&gt;
&lt;p&gt;[6] The new &lt;a href="http://programmingzen.com/recommends/?B002GYWHSQ"&gt;Kindle DX&lt;/a&gt; on Amazon.&lt;/p&gt;
&lt;p&gt;[7] &lt;a href="http://www.pomodorotechnique.com/"&gt;The Pomodoro Technique&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[8] &lt;a href="http://www.apple.com/downloads/macosx/development_tools/pomodoro.html"&gt;Pomodoro&lt;/a&gt; for Mac OS X.&lt;/p&gt;
&lt;p&gt;[9] &lt;a href="http://en.wikipedia.org/wiki/Sprezzatura"&gt;Sprezzatura&lt;/a&gt; on Wikipedia.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Translations&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Carlos Marcelo Cabrera translated this article into Spanish: &lt;a href="http://pointtonull.esdebian.org/42312/busqueda-excelencia-programacion"&gt;La búsqueda de la excelencia en la programación&lt;/a&gt;.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=rmbcXmVN3Jo:6FeAUi4ROyo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=rmbcXmVN3Jo:6FeAUi4ROyo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=rmbcXmVN3Jo:6FeAUi4ROyo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=rmbcXmVN3Jo:6FeAUi4ROyo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=rmbcXmVN3Jo:6FeAUi4ROyo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=rmbcXmVN3Jo:6FeAUi4ROyo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=rmbcXmVN3Jo:6FeAUi4ROyo:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=rmbcXmVN3Jo:6FeAUi4ROyo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=rmbcXmVN3Jo:6FeAUi4ROyo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/rmbcXmVN3Jo" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/07/04/the-pursuit-of-excellence-in-programming/#comments" thr:count="45" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/07/04/the-pursuit-of-excellence-in-programming/feed/atom/" thr:count="45" />
		<thr:total>45</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/07/04/the-pursuit-of-excellence-in-programming/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[The Great Ruby Shootout (Windows Edition)]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/wNpuTrF_rk8/" />
		<id>http://programmingzen.com/?p=1220</id>
		<updated>2010-07-04T07:19:35Z</updated>
		<published>2010-06-28T19:00:28Z</published>
		<category scheme="http://programmingzen.com" term="Ruby" /><category scheme="http://programmingzen.com" term="Ruby Benchmark Suite" />		<summary type="html"><![CDATA[This post contains the results of a Ruby shootout on Windows that I recently conducted. You can find the Mac edition, published last month, here. I was planning to have this one ready much sooner, but a couple of serious events in personal life prevented that from happening. Be sure to grab my feed or [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/">&lt;p&gt;This post contains the results of a Ruby shootout on Windows that I recently conducted. You can find the Mac edition, published last month, &lt;a href="http://programmingzen.com/2010/05/16/benchmarking-macruby-0-6/"&gt;here&lt;/a&gt;. I was planning to have this one ready much sooner, but a couple of serious events in personal life prevented that from happening. Be sure to grab &lt;a href="http://feeds2.feedburner.com/ZenAndTheArtOfRubyProgramming"&gt;my feed&lt;/a&gt; or &lt;a href="http://antoniocangiano.us1.list-manage1.com/subscribe?u=9fd2908bf379ac3d3b9f2d8e3&amp;#038;id=cec4240b96"&gt;join the newsletter&lt;/a&gt; to avoid missing the upcoming Linux shootout.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The setup&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For this shootout I included a subset of the &lt;a href="http://github.com/acangiano/ruby-benchmark-suite"&gt;Ruby Benchmark Suite&lt;/a&gt;. I opted to primarily exclude tests that were executed in fractions of a second in most VMs, focusing instead of more substantial benchmarks (several of which come from the Computer Language Benchmarks Game). The best times out of five runs are reported here for each benchmark.&lt;/p&gt;
&lt;p&gt;All tests were run on Windows 7 x64, on an Intel Core 2 Quad Q6600 2.40 GHz, 8 GB DDR2 RAM, with two 500 GB 7200 rpm disks.&lt;/p&gt;
&lt;p&gt;The implementations tested were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ruby 1.8.7&lt;/strong&gt; (2010-01-10 patchlevel 249) [i386-mingw32] (RubyInstaller)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ruby 1.9.1 p378&lt;/strong&gt; (2010-01-10 revision 26273) [i386-mingw32] (RubyInstaller)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ruby 1.9.2 dev&lt;/strong&gt; (2010-05-31) [i386-mingw32] (experimental)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JRuby 1.5.1&lt;/strong&gt; (ruby 1.8.7 patchlevel 249) (2010-06-06 f3a3480) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_20) [amd64-java]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IronRuby 1.0&lt;/strong&gt; x64 for .NET 4.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;JRuby was run with the &lt;code&gt;--fast&lt;/code&gt; and &lt;code&gt;--server&lt;/code&gt; optimization flags.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Synthetic benchmarks cannot predict how fast your programs will be when dealing with a particular implementation. They provide an (entertaining) educated guess, but &lt;strong&gt;you shouldn&amp;#8217;t draw overly definitive conclusions from them&lt;/strong&gt;. The values reported here should be assumed to be characteristic of server-side &amp;#8211; and long running &amp;#8211; processes and should be taken with a grain of salt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The results&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Please find below the execution times for the selected tests. Timeouts indicate that the execution of a single iteration for a given test took more than 60 seconds and had to be interrupted. Bold values indicate the best performance for each test.&lt;/p&gt;
&lt;p style="text-align: center;" align="center"&gt;
	&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/rbs-win.png" alt="RBS Windows Shootout" /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Despite a couple of errors and a few timeouts, JRuby was the fastest of the lot, which can be seen as impressive&lt;del datetime="2010-07-04T02:18:01+00:00"&gt; if we consider that this is Windows we are talking about after all&lt;/del&gt;.&lt;/p&gt;
&lt;p&gt;Ruby 1.9.1 and 1.9.2 were almost as fast as JRuby on these tests. With a few exceptions, the performances of the two 1.9 implementations were, expectedly, very similar.&lt;/p&gt;
&lt;p&gt;JRuby, 1.9.1 and 1.9.2 were all faster than the current MRI implementation, which can be seen as a prerequisite as we move, as a community, away from Ruby 1.8. Finally, it&amp;#8217;s worth noting that IronRuby&amp;#8217;s performance was however in line with that of Ruby 1.8.7.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update (July 3, 2010)&lt;/strong&gt;: The following box plot compares the various implementations for the tests for which all the implementations were successful. Only times for the largest successful input number were used in those tests where multiple input numbers were tested.&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/05/windows_shootout.png" alt="Windows Shootout Boxplot" /&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=wNpuTrF_rk8:GkTGOXxf1hM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=wNpuTrF_rk8:GkTGOXxf1hM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=wNpuTrF_rk8:GkTGOXxf1hM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=wNpuTrF_rk8:GkTGOXxf1hM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=wNpuTrF_rk8:GkTGOXxf1hM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=wNpuTrF_rk8:GkTGOXxf1hM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=wNpuTrF_rk8:GkTGOXxf1hM:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=wNpuTrF_rk8:GkTGOXxf1hM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=wNpuTrF_rk8:GkTGOXxf1hM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/wNpuTrF_rk8" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/#comments" thr:count="22" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/feed/atom/" thr:count="22" />
		<thr:total>22</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/06/28/the-great-ruby-shootout-windows-edition/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[How Microsoft is changing the programming world]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/31SY2q_6GHc/" />
		<id>http://programmingzen.com/?p=1215</id>
		<updated>2010-06-24T01:35:38Z</updated>
		<published>2010-06-23T17:00:26Z</published>
		<category scheme="http://programmingzen.com" term=".NET" /><category scheme="http://programmingzen.com" term="Programming Languages" />		<summary type="html"><![CDATA[Several years ago I knew a programmer, we&#8217;ll call him Joe, who fancied himself to be a great developer. He was a senior developer at &#8220;Big Co.&#8221;, who received a large enough pay check to just as easily compensate a few junior developers. The guy had Microsoft certifications, as expected of one in his position, [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/06/23/how-microsoft-is-changing-the-programming-world/">&lt;p&gt;Several years ago I knew a programmer, we&amp;#8217;ll call him Joe, who fancied himself to be a great developer. He was a senior developer at &amp;#8220;Big Co.&amp;#8221;, who received a large enough pay check to just as easily compensate a few junior developers.&lt;/p&gt;
&lt;p&gt;The guy had Microsoft certifications, as expected of one in his position, and he appeared to know Visual Studio inside and out, just as you&amp;#8217;d imagine. &lt;/p&gt;
&lt;p&gt;What was surprising for me at the time, was that as I got to know Joe better, I slowly started to realize that the guy was absolutely clueless about programming beyond the scope of the Microsoft bubble.&lt;/p&gt;
&lt;p&gt;He had never used Linux in his life, nor was he interested in learning about it. He wasn&amp;#8217;t aware of tools like CVS or SVN. He didn&amp;#8217;t seem familiar with the ideas behind unit testing or Agile methodologies; words like &amp;#8220;refactoring&amp;#8221; were outside of Joe&amp;#8217;s vocabulary.&lt;/p&gt;
&lt;p&gt;How about other programming languages or paradigms, like functional programming? Nope, nothing there either. He knew Visual Basic 6 and VB.NET, C# (the first release at the time) and a bit of C++. That&amp;#8217;s it. And he was proud of it. As I enquired further in an attempt to figure out what he was all about, he didn&amp;#8217;t mind admitting to a complete ignorance of what wasn&amp;#8217;t printed on Microsoft paper. &lt;/p&gt;
&lt;p&gt;What&amp;#8217;s interesting is that, despite his cluelessness &amp;#8211; due to a strict adherence to the Microsoft view of the programming world &amp;#8211; and perhaps a lack of intellectual curiosity, the guy did manage to be somewhat adequate at his job. Not spectacular by any stretch of the imagination, but good enough to keep his well paid job.&lt;/p&gt;
&lt;p&gt;Joe simply didn&amp;#8217;t care about tools and techniques that fell outside of the narrow, yet mainstream, beaten Microsoft path.&lt;/p&gt;
&lt;p&gt;Over the years I&amp;#8217;ve met countless Joes. In fact, if I were to generalize and characterize many Microsoft developers in the early 2000s, Joe would come to mind like an unpleasant stereotype.&lt;/p&gt;
&lt;p&gt;I tell this story not to criticize Joe or to claim that Microsoft developers suck. On the contrary, my argument is that Microsoft will be a key factor in terms of enabling functional programming to become mainstream. In fact, what Microsoft is doing is introducing .NET developers to functional programming, one piece at a time. &lt;/p&gt;
&lt;p&gt;Just a few days ago I was reading the blog of a guy who seemed happy to discover a cool &amp;#8220;new&amp;#8221; function called Zip in LINQ (hey Haskell programmer over there, stop laughing, you are disrupting my article). These days following blogs by Microsofties is in fact like witnessing some sort of Renaissance, with plenty of talk about exciting features that are clearly borrowed from the functional programming community.&lt;/p&gt;
&lt;p&gt;The evolution of C# and Visual Basic, LINQ, and more recently the inclusion of F# as a fully supported language within the .NET Framework 4.0, all indicate Microsoft&amp;#8217;s new outlook towards functional programming. F# in particular is essentially OCaml for .NET, and has been received with open arms by the Microsoft community (as far as I can tell). &lt;/p&gt;
&lt;p&gt;There are very few books by mainstream publishers on OCaml. On the other hand, F# already has a rich ecosystem of &lt;a href="http://www.amazon.com/gp/search?ie=UTF8&amp;#038;keywords=F%23&amp;#038;tag=zenruby-20&amp;#038;index=books&amp;#038;linkCode=ur2&amp;#038;camp=1789&amp;#038;creative=9325"&gt;printed books&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=zenruby-20&amp;#038;l=ur2&amp;#038;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; that have been published by O&amp;#8217;Reilly, Apress, Wrox, Manning, and likely in the near future Microsoft itself. On top of that there are titles devoted to LINQ and countless books on the recent, more functional oriented, C# and VB.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not measuring the popularity of programming languages by the availability of books alone, but it&amp;#8217;s clear to me that there are millions of Joes out there who are ready to learn these new concepts that are now being put out and promoted by Microsoft. It doesn&amp;#8217;t matter that they&amp;#8217;re not new or that they&amp;#8217;re borrowed from other programming languages like Ruby, Python, LISP, ML, Haskell, etcetera.&lt;/p&gt;
&lt;p&gt;The end result of Microsoft&amp;#8217;s new approach is that now Joes everywhere are getting exposed to functional programming (masses of people who would otherwise be virtually shielded from the rest of the programming world).&lt;/p&gt;
&lt;p&gt;Microsoft may no longer be the influential powerhouse it once was, but I think it is fair to acknowledge the impact it&amp;#8217;s currently having on making functional programming, or at least some degree of it, more mainstream.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Initially I used the name &amp;#8220;Dick&amp;#8221; (short for Richard) to identify the programmer I talked about in this story. It was meant to be a humorous double entendre, but turned out to somewhat distract certain readers from the key points that this article was actually about. As well it seems that some people felt I was coming across as being strongly against Microsoft developers (which I&amp;#8217;m not in the least). As a result, some readers ended up being offended by this post, which was never my intention. I don&amp;#8217;t love political correctness, but I feel that replacing the name &amp;#8220;Dick&amp;#8221; with &amp;#8220;Joe&amp;#8221; instead ends up detracting less from the heart of the article.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=31SY2q_6GHc:sDZSXWxgHhE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=31SY2q_6GHc:sDZSXWxgHhE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=31SY2q_6GHc:sDZSXWxgHhE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=31SY2q_6GHc:sDZSXWxgHhE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=31SY2q_6GHc:sDZSXWxgHhE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=31SY2q_6GHc:sDZSXWxgHhE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=31SY2q_6GHc:sDZSXWxgHhE:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=31SY2q_6GHc:sDZSXWxgHhE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=31SY2q_6GHc:sDZSXWxgHhE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/31SY2q_6GHc" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/06/23/how-microsoft-is-changing-the-programming-world/#comments" thr:count="113" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/06/23/how-microsoft-is-changing-the-programming-world/feed/atom/" thr:count="113" />
		<thr:total>113</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/06/23/how-microsoft-is-changing-the-programming-world/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[Ten recent programming books that will make you a better developer]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/0ZGxQNqsdcU/" />
		<id>http://programmingzen.com/?p=1202</id>
		<updated>2010-06-21T12:23:03Z</updated>
		<published>2010-06-21T11:53:13Z</published>
		<category scheme="http://programmingzen.com" term="Books" /><category scheme="http://programmingzen.com" term="Reviews" />		<summary type="html"><![CDATA[Programming is the type of discipline that requires countless hours of dedication to reading and writing code, rather than purely theoretical learning from books. Yet programming books can be enlightening and provide guidance while one attempts to hone their craft in the pursuit of mastery. In this post I&#8217;ll share a (necessarily incomplete) list of [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/06/21/ten-recent-programming-books-that-will-make-you-a-better-developer/">&lt;p&gt;Programming is the type of discipline that requires countless hours of dedication to reading and writing code, rather than purely theoretical learning from books. Yet programming books can be enlightening and provide guidance while one attempts to hone their craft in the pursuit of mastery.&lt;/p&gt;
&lt;p&gt;In this post I&amp;#8217;ll share a (necessarily incomplete) list of relatively new books that I believe will make most developers better programmers. By &amp;#8220;new&amp;#8221;, I mean books that have been released recently (within the past three years), that haven&amp;#8217;t become classics yet or appeared in everyone else&amp;#8217;s list of recommended programming books. Hence, you won&amp;#8217;t find &lt;a href="http://programmingzen.com/recommends/?0262011530"&gt;SICP&lt;/a&gt;, &lt;a href="http://programmingzen.com/recommends/?0201485419"&gt;TAoCP&lt;/a&gt;, &lt;a href="http://programmingzen.com/recommends/?0521663504"&gt;PFDS&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;Please note that each of them deserves (and probably will receive at some time) a lengthy review. Here I simply state in a brief manner why I think they are important.&lt;/p&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 260px;"&gt;
&lt;p&gt;&lt;strong&gt;1. &lt;a href="http://programmingzen.com/recommends/?0262033844"&gt;Introduction to Algorithms, Third Edition&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?0262033844"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/introduction-to-algorithms.jpg" alt="Introduction to Algorithms Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;OK, this is cheating a little. &amp;#8220;Introduction to Algorithms&amp;#8221; is both a classic and a book on everyone&amp;#8217;s list. However, I opted to include it because not everyone knows that it was recently (September 2009) released in its third edition. The book received a major upgrade to the existing content and exercises, as well as including new, modern algorithms. Any programmer working through this book, or revisiting it, will learn valuable, foundational knowledge.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 350px;"&gt;
&lt;p&gt;&lt;strong&gt;2. &lt;a href="http://programmingzen.com/recommends/?0470229055"&gt;The Annotated Turing&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?0470229055"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/the-annotated-turing.jpg" alt="The Annotated Turing Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;Alan Turing wrote a classic paper in 1936 with the title: &amp;#8220;&lt;a href="http://www.google.com/search?q=On+Computable+Numbers,+with+an+Application+to+the+Entscheidungsproblem"&gt;On Computable Numbers, with an Application to the Entscheidungsproblem&lt;/a&gt;&amp;#8220;. It was a paper on Turing machines and the limits of computability, which had a major impact on computer science and the development of the computer you are reading this post on. Every programmer/computer scientist should get ahold of this paper and read it. Unfortunately, it isn&amp;#8217;t exactly easy to grasp if you are not used to reading research papers. In &amp;#8220;The Annotated Turing&amp;#8221;, Petzold does a marvelous job of dissecting the paper (and its errata), providing ample explanations and background information over 18 chapters (360 pages vs 36 of the original paper). It manages to be rigorous while still being accessible. If this book doesn&amp;#8217;t arouse your interest in computer science, chances are nothing will.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 260px;"&gt;
&lt;p&gt;&lt;strong&gt;3. &lt;a href="http://programmingzen.com/recommends/?0321503627"&gt;Growing Object-Oriented Software, Guided by Tests&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?0321503627"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/growing-oo-sw.jpg" alt="Growing OO Software Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;This book takes two fundamental pillars of modern software development, Object-Oriented Design and Test-Driven Development, and clearly illustrates how to apply the best practices of each to build and maintain complex software. I don&amp;#8217;t know of many developers who couldn&amp;#8217;t learn something new about TDD in the context of OOP from this book. A must read.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 260px;"&gt;
&lt;p&gt;&lt;strong&gt;4. &lt;a href="http://programmingzen.com/recommends/?0132350882"&gt;Clean Code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?0132350882"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/clean-code.jpg" alt="Clean Code Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;While on the subject of Agile development, I can&amp;#8217;t help but recommend &amp;#8220;Clean Code&amp;#8221; by Uncle Bob. It compliments &amp;#8220;Growing Object-Oriented Software, Guided by Tests&amp;#8221; perfectly by focusing on how to improve and refractor code to get rid of code smells. You can think of it as a very succinct version of Code Complete 2, with a strong focus on Agile craftsmanship. The examples, as per the previous book, are in Java but that shouldn&amp;#8217;t be much of an issue for the open-minded developer.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 275px;"&gt;
&lt;p&gt;&lt;strong&gt;5. &lt;a href="http://programmingzen.com/recommends/?0321620704"&gt;Leading Lean Software Development: Results Are not the Point&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?0321620704"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/leading-lean-sw-dev.jpg" alt="Leading Lean Software Development Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;Lean principles deriving from the Lean manufacturing world have been effectively translated and adapted to the field of software development. This book explains how to lead a team to success through lean software development in detail to team leaders and mentors. Having obtained a Lean Six Sigma yellow belt many years ago, this book definitely gave me a few flashbacks. If you are not familiar with the concepts presented, you&amp;#8217;ll definitely find it food for thought. Building software requires far more than just writing quality code, and the techniques presented here are valuable, even if you don&amp;#8217;t fully buy into this methodology.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 260px;"&gt;
&lt;p&gt;&lt;strong&gt;6. &lt;a href="http://programmingzen.com/recommends/?1593271832"&gt;Growing Software&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?1593271832"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/growing-software.jpg" alt="Growing Software Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;While on the subject of leadership, if you are in charge of software development at a small company or startup, you want to read this book. My interest in this title came from the fact that its author (Louis Testa) works as a Senior Engineering Manager at Galois, a company that uses Haskell as their technological advantage (and hired Don Stewart of Haskell fame). &amp;#8220;Growing Software&amp;#8221; delivered on my expectations and is full of hands-on advice on how to deal with the whole workflow surrounding the creation of software from the idea all the way to the sale and support of a product.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 260px;"&gt;
&lt;p&gt;&lt;strong&gt;7. &lt;a href="http://programmingzen.com/recommends/?1593271743"&gt;The Art of Debugging with GDB, DDD, and Eclipse&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?1593271743"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/art-of-debugging.jpg" alt="The Art of Debugging Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;Debugging is an invaluable skill and one that is often left out from introductory programming books. Being able to effectively debug code is what separate professionals from beginners, and productive programmers from frustrated ones. This book is ruthlessly practical with many advanced techniques for debugging on Linux/Unix. It&amp;#8217;s well worth its price in my opinion.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 260px;"&gt;
&lt;p&gt;&lt;strong&gt;8. &lt;a href="http://programmingzen.com/recommends/?1590597451"&gt;Applied Mathematics for Database Professionals&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?1590597451"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/applied-math-db.jpg" alt="Applied Mathematics for Database Professionals Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;Assuming you already have a decent understanding of relational databases, and are not too scared of mathematics, this book will really bring your knowledge of how databases work to the next level, in turn improving the design, schema evolution, and SQL queries you&amp;#8217;ll create afterwards.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 260px;"&gt;
&lt;p&gt;&lt;strong&gt;9. &lt;a href="http://programmingzen.com/recommends/?0596529325"&gt;Programming Collective Intelligence&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?0596529325"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/collective-intelligence.jpg" alt="Programming Collective Intelligence Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;If you are building web applications that do more than simply CRUD operations on your data, you&amp;#8217;ll want to read this book (with examples in Python). The motivated, intermediate developer will learn how to efficiently solve complex problems related to machine learning and intelligent web algorithms from this book. It&amp;#8217;s a very accessible introduction to tough subjects and one of the most interesting books I&amp;#8217;ve read in some time.&lt;/p&gt;
&lt;/div&gt;
&lt;div style="margin-bottom: 20px; border: 1px solid #ccc; padding: 5px 15px 5px 15px; height: 260px;"&gt;
&lt;p&gt;&lt;strong&gt;10. &lt;a href="http://programmingzen.com/recommends/?1430219483"&gt;Coders at work&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://programmingzen.com/recommends/?1430219483"&gt;&lt;img src="http://programmingzen.com/wp-content/uploads/2010/06/coders-at-work.jpg" alt="Coders at work Image" align="left" style="float: left; margin-right: 10px;" /&gt;&lt;/a&gt;To conclude this list, I wanted to include a book that&amp;#8217;s aimed at showing programmers how some of the best programmers and computer scientists do their work. I previously enjoyed &lt;a href="http://programmingzen.com/recommends/?1430210788"&gt;Founders at Work&lt;/a&gt;, and this version about programming is just as good. It&amp;#8217;s inspiring, fun to read, and rich in insight and advice.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=0ZGxQNqsdcU:b2TQt_KqVaU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=0ZGxQNqsdcU:b2TQt_KqVaU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=0ZGxQNqsdcU:b2TQt_KqVaU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=0ZGxQNqsdcU:b2TQt_KqVaU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=0ZGxQNqsdcU:b2TQt_KqVaU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=0ZGxQNqsdcU:b2TQt_KqVaU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=0ZGxQNqsdcU:b2TQt_KqVaU:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=0ZGxQNqsdcU:b2TQt_KqVaU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=0ZGxQNqsdcU:b2TQt_KqVaU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/0ZGxQNqsdcU" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/06/21/ten-recent-programming-books-that-will-make-you-a-better-developer/#comments" thr:count="13" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/06/21/ten-recent-programming-books-that-will-make-you-a-better-developer/feed/atom/" thr:count="13" />
		<thr:total>13</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/06/21/ten-recent-programming-books-that-will-make-you-a-better-developer/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[A new domain name for Zen and the Art of Programming]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/Z0zupm65LzA/" />
		<id>http://programmingzen.com/?p=1201</id>
		<updated>2010-06-20T10:42:12Z</updated>
		<published>2010-06-20T10:16:49Z</published>
		<category scheme="http://programmingzen.com" term="General" />		<summary type="html"><![CDATA[For years Zen and the Art of Programming has been hosted on my domain antoniocangiano.com. However, I&#8217;ve decided to switch it over to a new one, programmingzen.com. This move was done for two main reasons: first, it is sometimes hard for native English speakers to communicate and remember my name. Second, my blog isn&#8217;t so [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/06/20/a-new-domain-name-for-zen-and-the-art-of-programming/">&lt;p&gt;For years Zen and the Art of Programming has been hosted on my domain antoniocangiano.com. However, I&amp;#8217;ve decided to switch it over to a new one, &lt;a href="http://programmingzen.com"&gt;programmingzen.com&lt;/a&gt;. This move was done for two main reasons: first, it is sometimes hard for native English speakers to communicate and remember my name. Second, my blog isn&amp;#8217;t so much about me and my life, as it is about the world of programming.&lt;/p&gt;
&lt;p&gt;As I look towards the steps that are required to bring my blog to the next level, I decided it was time to make the switch to a new domain. I&amp;#8217;d like to transform Zen and the Art of Programming into a blog that every programmer could potentially be interested in subscribing to, not just people who are into Ruby or following me.&lt;/p&gt;
&lt;p&gt;The good news for you is that you don&amp;#8217;t need to do a thing. Every internal link has been permanently redirected to a corresponding programmingzen.com link, with the exception of the homepage. I&amp;#8217;m now using &lt;a href="http://antoniocangiano.com/"&gt;antoniocangiano.com&lt;/a&gt; as a sort of minimalist virtual business card, from which I link to my email, &lt;a href="http://twitter.com/acangiano"&gt;Twitter&lt;/a&gt;, Linkedin, my three blogs (this, my personal blog, and my math blog), as well as my book and &lt;a href="http://thinkcode.tv"&gt;ThinkCode.TV&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Stay tuned for lots of interesting new content, which I plan to post more frequently. Meanwhile please feel free to let me know what you think about this new change; I&amp;#8217;d really welcome your thoughts.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Z0zupm65LzA:ILNO64ajL1w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Z0zupm65LzA:ILNO64ajL1w:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=Z0zupm65LzA:ILNO64ajL1w:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Z0zupm65LzA:ILNO64ajL1w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=Z0zupm65LzA:ILNO64ajL1w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Z0zupm65LzA:ILNO64ajL1w:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Z0zupm65LzA:ILNO64ajL1w:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=Z0zupm65LzA:ILNO64ajL1w:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=Z0zupm65LzA:ILNO64ajL1w:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/Z0zupm65LzA" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/06/20/a-new-domain-name-for-zen-and-the-art-of-programming/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/06/20/a-new-domain-name-for-zen-and-the-art-of-programming/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/06/20/a-new-domain-name-for-zen-and-the-art-of-programming/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Antonio Cangiano</name>
						<uri>http://antoniocangiano.com</uri>
					</author>
		<title type="html"><![CDATA[Would you use a Mac mini as your development machine?]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ZenAndTheArtOfRubyProgramming/~3/fvf2imO3QO8/" />
		<id>http://antoniocangiano.com/?p=1196</id>
		<updated>2010-06-17T11:29:15Z</updated>
		<published>2010-06-17T11:23:53Z</published>
		<category scheme="http://programmingzen.com" term="Cocoa and Objective-C" /><category scheme="http://programmingzen.com" term="Industry News" /><category scheme="http://programmingzen.com" term="Mac" /><category scheme="http://programmingzen.com" term="iPhone OS Development" />		<summary type="html"><![CDATA[Apple just released a brand new, gorgeous looking Mac mini. This major upgrade brings us two different models: a desktop one and a server version (priced at $699 and $999, respectively). Equipped with a HDMI port, the desktop edition of the Mac mini makes for a perfect Home Theater PC. It&#8217;s small and stylish, and [...]]]></summary>
		<content type="html" xml:base="http://programmingzen.com/2010/06/17/would-you-use-a-mac-mini-as-your-development-machine/">&lt;p align="center"&gt;&lt;img src="http://antoniocangiano.com/wp-content/uploads/2010/06/macmini.png" alt="MacMini Image" /&gt;&lt;/p&gt;
&lt;p&gt;Apple just released a brand new, gorgeous looking &lt;a href="http://www.apple.com/macmini/"&gt;Mac mini&lt;/a&gt;. This major upgrade brings us two different models: a desktop one and a server version (priced at $699 and $999, respectively).
&lt;/p&gt;
&lt;p&gt;Equipped with a HDMI port, the desktop edition of the Mac mini makes for a perfect Home Theater PC. It&amp;#8217;s small and stylish, and as such is a great fit in your living room. Most of the reviews I&amp;#8217;ve read focus on its use as a highly capable HTPC (despite its lack of a Blu-Ray drive).
&lt;/p&gt;
&lt;p&gt;However, I see the new Mac Mini in a different light. At $700 it is far too expensive for a HTPC, yet it&amp;#8217;s ideal as an entry-level machine for web, Mac, and iOS development (it&amp;#8217;s almost as cheap as a Hackintosh, minus the headache).&lt;/p&gt;
&lt;p&gt;Mac Minis will do the job and be more than capable thanks to their adequate, albeit not spectacular, hardware specs. If my MacBook Pro were to die today, I would definitely consider purchasing one for development purposes. Would you?&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=fvf2imO3QO8:gUhA59BwfEU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=fvf2imO3QO8:gUhA59BwfEU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=fvf2imO3QO8:gUhA59BwfEU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=fvf2imO3QO8:gUhA59BwfEU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=fvf2imO3QO8:gUhA59BwfEU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=fvf2imO3QO8:gUhA59BwfEU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=fvf2imO3QO8:gUhA59BwfEU:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?a=fvf2imO3QO8:gUhA59BwfEU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ZenAndTheArtOfRubyProgramming?i=fvf2imO3QO8:gUhA59BwfEU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ZenAndTheArtOfRubyProgramming/~4/fvf2imO3QO8" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://programmingzen.com/2010/06/17/would-you-use-a-mac-mini-as-your-development-machine/#comments" thr:count="17" />
		<link rel="replies" type="application/atom+xml" href="http://programmingzen.com/2010/06/17/would-you-use-a-mac-mini-as-your-development-machine/feed/atom/" thr:count="17" />
		<thr:total>17</thr:total>
	<feedburner:origLink>http://programmingzen.com/2010/06/17/would-you-use-a-mac-mini-as-your-development-machine/</feedburner:origLink></entry>
	</feed><!-- Dynamic page generated in 3.506 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-07-31 06:10:19 --><!-- Compression = gzip -->
