<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" version="2.0">
  <channel>
    <title>No Fluff Just Stuff</title>
    <link>http://www.nofluffjuststuff.com</link>
    <description>No Fluff Just Stuff</description>
    <item>
      <title>Live Service Reloading in Tapestry 5.2</title>
      <link>http://www.nofluffjuststuff.com/blog/howard_lewis_ship/2010/03/live_service_reloading_in_tapestry_5_2_1</link>
      <description>&lt;p&gt;A common question I get during &lt;a href="http://howardlewisship.com/training.html"&gt;Tapestry training sessions&lt;/a&gt; is: &lt;em&gt;Why can't Tapestry reload my services as well as my pages and components?&lt;/em&gt;.  It does seem odd that I talk about how agile Tapestry is, with the live class reloading, and how nicely OO it is, what with services ... but when you move common logic to a service, you lose the agility because services do not live reload.

&lt;p&gt;This came up yet again, during my &lt;a href="http://skillsmatter.com/course-details/java-jee/tapestry-web-development"&gt;latest training session, in London&lt;/a&gt;.

&lt;p&gt;I've considered this before, and I've been opposed to live service reloading for a couple of reasons. First, live reloading requires creating new class loaders, and that causes conflicts with other frameworks and libraries. You get those crazy ClassCastExceptions even though the class name is correct (same name, different class loader, different class).  Further, in Tapestry IoC, services can be utilized to make contributions to other services ... changing one service implementation, or one module, can cause a ripple effect across an untraceable number of other services. How do you know what needs to be reloaded or re-initialized?

&lt;p&gt;
When I last really considered this, back in the HiveMind days, my conclusion was that it was not possible to create a perfect reloading process: one that would ensure that the live-reloaded Registry (and all of its services with all their internal state) would be an exact match for what configuration you'd get by doing a cold restart.

&lt;p&gt;So I shelved the idea, thinking that simply redeploying the WAR containing the application (and the services and modules) would accomplish the desired effect.

&lt;p&gt;
But as they say, &lt;strong&gt;The Perfect Is The Enemy Of The Good&lt;/strong&gt;.  One very sharp student, &lt;a href="http://homepage.mac.com/pardeike/resume.html"&gt;Andreas Pardeike&lt;/a&gt;, asked: &lt;em&gt;Why not just reload the service implementations?&lt;/em&gt;.

&lt;p&gt;
Why not indeed?  Why not limit the behavior to something understandable, trackable, and not very expensive.  Most of the infrastructure was already present, used for reloading of component classes. What about ClassCastExceptions?  In Tapestry, service implementations are already buried under multiple layers of dynamically generated proxies that implement the service interface. The underlying service implementation is never automatically exposed.

&lt;p&gt;
A few hours of work later ... and we have live service reloading. Each reloadable service gets its own class loader, just to load the service implementation class. When Tapestry is  periodically checking for updated files, it checks each reloadable service. If necessary, the existing instance, class and class loader is discarded and a new class loader created for the updated .class file.

&lt;p&gt;
This is going to make a big difference for me, and for most Tapestry developers. Both applications I'm working on have enough Hibernate entities and other clutter to take some time (20 - 30 seconds) to restart, and most functionality is hidden past a login page. Being able to change a service, for example to tweak a Hibernate query, with the same speed with which I can tweak a template or component class, is just one more thing to keep me &lt;a href="http://en.wikipedia.org/wiki/Flow_(psychology)"&gt;in the flow&lt;/a&gt; and super productive.

&lt;p&gt;
Give it a try ... it's one more step towards making Tapestry so compelling, you wouldn't think of using anything else!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-1640769601284894714?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/VbQipguiWcw" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 15 Mar 2010 13:13:00 CDT</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-1640769601284894714</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Procrastination and JavaOne 2010: See you in 2011!</title>
      <link>http://www.nofluffjuststuff.com/blog/howard_lewis_ship/2010/03/procrastination_and_javaone_2010_see_you_in_2011_</link>
      <description>&lt;p&gt;Well, that's what I get for waiting until the last day ... by the time I had a chance to put together a submission or two for JavaOne 2010, the site was down (from about 10pm on). Kind of frustrating, I was looking forward to talking about Tapestry and Clojure (my main speaking staples) in front of another big crowd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-7169931906856834633?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/lilxGl2snLg" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 15 Mar 2010 10:30:23 CDT</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-7169931906856834633</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Open Source Update: jQuery PeriodicalUpdater, TestingLabs, GPars, etc.</title>
      <link>http://www.nofluffjuststuff.com/blog/robert_fischer/2010/03/open_source_update_jquery_periodicalupdater_testinglabs_gpars_etc_</link>
      <description>&lt;p&gt;I&amp;#8217;ve done a fair bit of fairly small open source updates recently.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;jQuery PeriodicalUpdater&lt;/code&gt;: The main function now returns a handle that can be used to call &lt;code&gt;stop()&lt;/code&gt;, thereby ignoring any updates that may come back and preventing future updates from being sent.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TestingLabs&lt;/code&gt;: I released TestingLabs 0.4 to work with Grails 1.2.0. Had a bug with versioning under Grails: &lt;a rel="nofollow" target="_blank" href="http://jira.codehaus.org/browse/GRAILSPLUGINS-2023"&gt;More info on JIRA&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Presentations&lt;/code&gt;: I&amp;#8217;m now storing the slides for my presentations on GitHub. They&amp;#8217;re under a Creative Commons License.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ClosureBridge&lt;/code&gt;: This is a tiny library (up on &lt;a rel="nofollow" target="_blank" href="http://repo.smokejumperit.com"&gt;the repo.smokejumperit.com Maven repo&lt;/a&gt;) that provides a link between Groovy&amp;#8217;s Closures and Callable/Runnable/Java code.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Fun with GPars&lt;/code&gt;: A small library where I was experimenting with GPars&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPars&lt;/code&gt;: Submitted a fix and generally been discussing things with the GPars community (and by that, I mean Vacalv Pech)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a rel="nofollow" target="_blank" href="https://github.com/RobertFischer"&gt;my GitHub page&lt;/a&gt; for more info.&lt;/p&gt;
&lt;hr /&gt;
This post was by &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/author/candide/"&gt;Robert Fischer&lt;/a&gt;, written on March 12, 2010.&lt;br /&gt;
Comment on this post: &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/os-update-march2010/#respond"&gt;http://enfranchisedmind.com/blog/posts/os-update-march2010/#respond&lt;/a&gt;&lt;br /&gt;
Public Permalink: &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/os-update-march2010/"&gt;http://enfranchisedmind.com/blog/posts/os-update-march2010/&lt;/a&gt;
&lt;hr /&gt;&lt;a rel="nofollow" target="_blank" href="http://creativecommons.org/licenses/by-sa/3.0/us/"&gt;&lt;img alt="Creative Commons License" style="border-width:0;" src="http://i.creativecommons.org/l/by-sa/3.0/us/88x31.png"/&gt;&lt;/a&gt;&lt;br /&gt;This article was a post on &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog"&gt;the EnfranchisedMind blog&lt;/a&gt;. &lt;span&gt;EnfranchisedMind Blog&lt;/span&gt; by &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/"&gt;Robert Fischer, Brian Hurt, and Other Authors&lt;/a&gt; is licensed under a &lt;a rel="nofollow" target="_blank" href="http://creativecommons.org/licenses/by-sa/3.0/us/"&gt;Creative Commons Attribution-Share Alike 3.0 United States License&lt;/a&gt;.&lt;p style="display:none;"&gt;(Digital Fingerprint: bcecb67d74ab248f06f068724220e340 (203.215.201.194) )&lt;/p&gt;</description>
      <pubDate>Fri, 12 Mar 2010 12:28:00 CST</pubDate>
      <guid isPermaLink="true">http://enfranchisedmind.com/blog/?p=2353</guid>
      <dc:creator>Robert Fischer</dc:creator>
    </item>
    <item>
      <title>Live Service Reloading in Tapestry 5.2</title>
      <link>http://www.nofluffjuststuff.com/blog/howard_lewis_ship/2010/03/live_service_reloading_in_tapestry_5_2</link>
      <description>&lt;p&gt;A common question I get during &lt;a href="http://howardlewisship.com/training.html"&gt;Tapestry training sessions&lt;/a&gt; is: &lt;em&gt;Why can't Tapestry reload my services as well as my pages and components?&lt;/em&gt;.  It does seem odd that I talk about how agile Tapestry is, with the live class reloading, and how nicely OO it is, what with services ... but when you move common logic to a service, you lose the agility because services do not live reload.

&lt;p&gt;This came up yet again, during my &lt;a href="http://skillsmatter.com/course-details/java-jee/tapestry-web-development"&gt;latest training session, in London&lt;/a&gt;.

&lt;p&gt;I've considered this before, and I've been opposed to live service reloading for a couple of reasons. First, live reloading requires creating new class loaders, and that causes conflicts with other frameworks and libraries. You get those crazy ClassCastExceptions even though the class name is correct (same name, different class loader, different class).  Further, in Tapestry IoC, services can be utilized to make contributions to other services ... changing one service implementation, or one module, can cause a ripple effect across an untraceable number of other services. How do you know what needs to be reloaded or re-initialized?

&lt;p&gt;
When I last really considered this, back in the HiveMind days, my conclusion was that it was not possible to create a perfect reloading process: one that would ensure that the live-reloaded Registry (and all of its services with all their internal state) would be an exact match for what configuration you'd get by doing a cold restart.

&lt;p&gt;So I shelved the idea, thinking that simply redeploying the WAR containing the application (and the services and modules) would accomplish the desired effect.

&lt;p&gt;
But as they say, &lt;strong&gt;The Perfect Is The Enemy Of The Good&lt;/strong&gt;.  One very sharp student, &lt;a href="http://homepage.mac.com/pardeike/resume.html"&gt;Andreas Pardeike&lt;/a&gt;, asked: &lt;em&gt;Why not just reload the service implementations?&lt;/em&gt;.

&lt;p&gt;
Why not indeed?  Why not limit the behavior to something understandable, trackable, and not very expensive.  Most of the infrastructure was already present, used for reloading of component classes. What about ClassCastExceptions?  In Tapestry, service implementations are already buried under multiple layers of dynamically generated proxies that implement the service interface. The underlying service implementation is never automatically exposed.

&lt;p&gt;
A few hours of work later ... and we have live service reloading. Each reloadable service gets its own class loader, just to load the service interface class. When Tapestry is  periodically checking for updated files, it checks each reloadable service. If necessary, the existing instance, class and class loader is discarded and a new class loader created for the updated .class file.

&lt;p&gt;
This is going to make a big difference for me, and for most Tapestry developers. Both applications I'm working on have enough Hibernate entities and other clutter to take some time (20 - 30 seconds) to restart, and most functionality is hidden past a login page. Being able to change a service, for example to tweak a Hibernate query, with the same speed with which I can tweak a template or component class, is just one more thing to keep me &lt;a href="http://en.wikipedia.org/wiki/Flow_(psychology)"&gt;in the flow&lt;/a&gt; and super productive.

&lt;p&gt;
Give it a try ... it's one more step towards making Tapestry so compelling, you wouldn't think of using anything else!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-1640769601284894714?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/VbQipguiWcw" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 12 Mar 2010 12:00:35 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-1640769601284894714</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Why Eclipse leaves me wanting</title>
      <link>http://www.nofluffjuststuff.com/blog/howard_lewis_ship/2010/03/why_eclipse_leaves_me_wanting</link>
      <description>&lt;p&gt;I think I've come to understand why Eclipse leaves me always feeling a bit frustrated.  Yes, it is more stable than IDEA, uses less memory, has some documentation, and a lot of acceptance ... but even so, it just leaves me cold (and I was an early adopter, signed up for the beta way back in 2000!).

&lt;h3&gt;Keystrokes are &lt;strong&gt;not&lt;/strong&gt; modal&lt;/h3&gt;

&lt;p&gt;
The fact that I can type a common keystroke into an Eclipse window and not know what it will do is painful. How a keystroke is interpreted depends on what perspective is active, what view or editor has focus, and what kind of data is being edited in the editor.  That's &lt;strong&gt;dead wrong&lt;/strong&gt;; keystrokes are about muscle memory, and muscle memory remembers motion, not context. The end result is that I get frustrated hitting keystrokes and seeing nothing happening. It doesn't help that I cycle between Mac and a PC on most days.

&lt;h3&gt;You &lt;strong&gt;can't&lt;/strong&gt; have it your way&lt;/h3&gt;

&lt;p&gt;
A tool as powerful and extensible as Eclipse walks the tightrope of offering lots of features and customizations without overwhelming the user. Alas, Eclipse is lying in a broken heap fifty feet below that tightrope.  Eclipse has an unending set of options and defaults for things I don't care about, but anything I do care about seems to never be presents.  Here's a few ideas of the top of my head:

&lt;ul&gt;
&lt;li&gt;Stop running launches when I close the project (I often have to kill them from the command line)&lt;/li&gt;
&lt;li&gt;Give me a quick way to stop all running launches&lt;/l1&gt;
&lt;li&gt;Why so many steps to implement an interface? It's the second most common thing I do!&lt;/li&gt;
&lt;li&gt;How about a button to quickly relaunch the current running launch?&lt;/li&gt;
&lt;li&gt;Why are the available refactorings so paltry and where are the 3rd party ones?
&lt;/ul&gt;

&lt;h3&gt;Who's eating their own dog food?&lt;/h3&gt;

&lt;p&gt;When I used IDEA, I was constantly struck by little details that showed that the IDE developers were also its prime users.  For example, it has open-type and open-resource dialogs much like Eclipse ... but each recognizes the keystroke for the other, so that if you mistakenly activate the open-type dialog, you just hit the normal keystroke to switch over to open-resource. Eclipse makes you cancel the dialog first.

&lt;p&gt;Another example: in IDEA if you rename a field, it notices the getter and setter and will offer to rename those as well.

&lt;p&gt;IDEA also has lots of quick fixes everywhere, such as "implement this interface" and lots of other tiny, cool things I miss every single day I use Eclipse. It's been about a year since I gave up on IDEA and I still miss it.

&lt;p&gt;Is it cultural or organizational?  Eclipse gives me the impression that day-to-day developers either have no concept of how the IDE gets used (and what rough spots are causing some serious chafing) &lt;em&gt;OR&lt;/em&gt; they are somehow prohibited from fixing things that are obviously wrong. 

&lt;h3&gt;If you love IDEA so much why don't you marry it?&lt;/h3&gt;

&lt;p&gt;So why don't I use IDEA anymore?  Two main reasons:  first, it's become very bloated, to the point that unless you go in and shut off a ton of features, it's unusable on my hardware. Merlyn has the same problem doing GWT work on his MacBook Pro ... all the help it gives you comes at a cost in terms of CPU and memory utilization and some instability.

&lt;p&gt;Secondly, I tried (even before IDEA went open source) to use IDEA in my training labs and I hit a stone wall of non-acceptance. Switching to Eclipse was a benefit to my students since, even running in Ubuntu instead of Windows, it was familiar and easy to navigate. It also out-performs IDEA inside my Ubuntu Virtual Machine.  I simply lack the ability to switch between the two on a constant basis without getting completely confused and frustrated. I had to choose  one, and I chose Eclipse: stable and accepted, even if it is brain dead.

&lt;h3&gt;Why call it Ugly?&lt;/h3&gt;

&lt;p&gt;One thing I don't get is how many people claim Eclipse is "ugly" and IDEA "beautiful".  I found IDEA to be overly chock-full of modal dialogs and a number of improperly resized (or non-resizable) dialogs and windows. It's a real dog's breakfast in terms of UI, and has the classically ugly Swing look and feel.

&lt;p&gt;I've always found Eclipse to look sharp and somewhat elegant. You can have a debate about the technical merits of SWT vs. AWT and Swing, or the ability to tune Swing to look like SWT ... but SWT out of the box is simply a better L&amp;F visually.  

&lt;p&gt;On a Mac they both suck at keyboard navigation, though.

&lt;p&gt;There, I've vented.  See what going cold-turkey from Twitter can do?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-7613338214682473566?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/t7UqTO_DIUQ" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 11 Mar 2010 18:41:15 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-7613338214682473566</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Actor style messaging and honey do lists</title>
      <link>http://www.nofluffjuststuff.com/blog/andrew_glover/2010/03/actor_style_messaging_and_honey_do_lists</link>
      <description>&lt;p&gt;&lt;img style="PADDING-LEFT: 1.0em; PADDING-RIGHT: 0.0em; PADDING-TOP: 0.0em; FLOAT: RIGHT; PADDING-BOTTOM: 0.0em" src="http://thediscoblog.com/images/2010/housewife.jpg" alt="free lunch" width="158" height="210"/&gt;As I previously mentioned in &amp;#8220;&lt;A HREF="http://thediscoblog.com/2010/03/03/free-lunches-mousetraps-and-the-actor-model/"&gt;Free lunches, mousetraps and the Actor model&lt;/A&gt;&amp;#8220;, Edward A. Lee wrote an interesting article entitled &amp;#8220;&lt;a href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf"&gt;The Problem with Threads&lt;/a&gt;&amp;#8221; in which he advocates leveraging the actor model in popular languages (such as in Java) as opposed to adopting an entire new paradigm (like &lt;a href="http://thediscoblog.com/2008/10/19/book-review-programming-erlang/"&gt;Erlang&lt;/a&gt;). He states:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;We should not replace established languages. We should instead build on them.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;It appears that more than a few hip people agree with his line of thinking. It turns out there are quite a few options available for leveraging the actor model in Java. That is, aside from alternative languages like &lt;a href="http://thediscoblog.com/2009/12/10/book-review-programming-scala/"&gt;Scala&lt;/a&gt;, which supports actors and &lt;A HREF="http://gpars.codehaus.org/"&gt;Groovy with GPars&lt;/A&gt;, there&amp;#8217;s framework&amp;#8217;s like &lt;A HREF="http://www.malhar.net/sriram/kilim/"&gt;Kilim&lt;/A&gt;, &lt;A HREF="http://osl.cs.uiuc.edu/af/"&gt;ActorFoundry&lt;/A&gt;, &lt;A HREF="http://actorsguildframework.org/"&gt;Actors Guild&lt;/A&gt;, and &lt;A HREF="http://code.google.com/p/jetlang/"&gt;jetlang&lt;/A&gt;.  &lt;/p&gt;
&lt;p&gt;I ended up employing Kilim at a client side over a year ago to replace a thread based computational model. At the time, GPars was in its early stages and I was specifically looking for a speed up in application performance. The multi-threaded application was taking roughly 5 hours to complete.  &lt;/p&gt;
&lt;p&gt;In the end, the speed up attributed to Kilim (or indirectly leveraging its actor model) was hardly noticeable (some aspects of &lt;A HREF="http://www.infoq.com/news/2008/06/kilim-message-passing-in-java"&gt;Kilim&lt;/A&gt; were noticeably faster though &amp;#8212; such as spawning a task was quite fast as opposed to spawning a normal threads) as the real performance gain was leveraged by reducing and improving database queries (as usual, performance issues were essentially IO bound); nevertheless, the prime benefit of Kilim, which at the time I had overlooked, was the notion of a &lt;I&gt;mailbox&lt;/I&gt;. That is, in the actor model, processes can &lt;I&gt;share data more safely&lt;/I&gt;. &lt;/p&gt;
&lt;p&gt;There are quite a few different implementations and ways to facilitate message passing in various languages and platforms, but to me, the actor model&amp;#8217;s mailbox notion is quite intuitive. In &lt;A HREF="http://java.dzone.com/articles/java-actors-with-kilim"&gt;Kilim&amp;#8217;s actor model&lt;/A&gt;, messages are passed between processes via a &lt;code&gt;Mailbox&lt;/code&gt; &amp;#8212; in many ways, you can think of it as a queue. Processes can put items into a mailbox and also pull items from a mailbox in both a blocking and non-blocking manner (blocking of the underlying process not a thread). &lt;/p&gt;
&lt;p&gt;As an example of leveraging mailboxes in Kilim, I wrote two actors (a &lt;code&gt;Husband&lt;/code&gt; and a &lt;code&gt;Wife&lt;/code&gt;) that extend from Kilim&amp;#8217;s &lt;code&gt;Task&lt;/code&gt; type. Previous versions of Kilim had an &lt;code&gt;Actor&lt;/code&gt; type; however, as of version 0.6, &lt;code&gt;Task&lt;/code&gt; is the way to go. &lt;/p&gt;
&lt;pre class="brush: java;"&gt;
import kilim.Mailbox;
import kilim.Pausable;
import kilim.Task;

public class Husband extends Task {
 private Mailbox&amp;lt;Message&amp;gt; mailbox;

 public Husband(Mailbox&amp;lt;Message&amp;gt; mailbox) {
  super();
  this.mailbox = mailbox;
 }

 @Override
 public void execute() throws Pausable, Exception {
  while (true) {
   System.out.println(&amp;quot;Husband listening...&amp;quot;);
   Message msg = mailbox.get(); // blocks
   if (msg.getReceipient() == Message.HUSBAND) {
    System.out.println(&amp;quot;Husband hears: &amp;quot; + msg.getMessage());
    Message reply = new Message(Message.WIFE, &amp;quot;Yes, dear&amp;quot;);
    mailbox.putnb(reply);
   }
   Task.sleep(1000);
  }
 }
}
&lt;/pre&gt;
&lt;p&gt;Under the covers, Kilim works by weaving bytecode so as to control &lt;code&gt;Task&lt;/code&gt; types and facilitate their safe interaction &amp;#8212; specifically, Kilim&amp;#8217;s weaver is looking for methods that throw the &lt;code&gt;Pausable&lt;/code&gt; type (previous versions used the &lt;code&gt;@Pausable&lt;/code&gt; annotation). &lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;Husband&lt;/code&gt; class, a few things are going on &amp;#8212; first, the instance waits for a message from a shared mailbox. In this case, I used a blocking &lt;code&gt;get&lt;/code&gt; call (as in reality, a husband really doesn&amp;#8217;t do anything else but waits for orders (I mean requests) from his wife). When a message is picked up, the instance checks to see if it was intended for it (in many cases, wife instances can communicate with children types sending messages like &amp;#8220;clean your room&amp;#8221; or &amp;#8220;brush your hair&amp;#8221;). &lt;/p&gt;
&lt;p&gt;Once a &lt;code&gt;Message&lt;/code&gt; type (which, in this case, is not a Kilim type) is determined to be sent to a &lt;code&gt;Husband&lt;/code&gt; instance, the &lt;code&gt;Husband&lt;/code&gt; type replies appropriately by creating a &lt;code&gt;Message&lt;/code&gt; and placing it into the &lt;code&gt;mailbox&lt;/code&gt; instance. Finally, the &lt;code&gt;sleep&lt;/code&gt; call is just placed to facilitate reading console output. &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Wife&lt;/code&gt; class is similar (expect that she doesn&amp;#8217;t wait to listen&amp;#8230;). Like the &lt;code&gt;Husband&lt;/code&gt; instance, this class creates a &lt;code&gt;Message&lt;/code&gt; (in the form of a Honey Do) and sends it off via the shared &lt;code&gt;MailBox&lt;/code&gt;; however, she doesn&amp;#8217;t wait around &amp;#8212; that is, the instance uses the &lt;code&gt;putnb&lt;/code&gt; call, which is non-blocking. What&amp;#8217;s more, she&amp;#8217;ll also attempt to see if anything is in the mailbox for her, but in her case, she also uses a non-blocking call (&lt;code&gt;getnb&lt;/code&gt;) like so:&lt;/p&gt;
&lt;pre class="brush: java;"&gt;
import kilim.Mailbox;
import kilim.Pausable;
import kilim.Task;

public class Wife extends Task {

 private Mailbox&amp;lt;Message&amp;gt; mailbox;

 public Wife(Mailbox&amp;lt;Message&amp;gt; mailbox) {
  super();
  this.mailbox = mailbox;
 }

 @Override
 public void execute() throws Pausable, Exception {
  while (true) {
   Message request = new Message(Message.HUSBAND,
    &amp;quot;Please do x, y, and z today, husband.&amp;quot;);

   mailbox.putnb(request);
   Task.sleep(1000);
   Message msg = mailbox.getnb(); // no block

   if (msg != null &amp;amp;&amp;amp; msg.getReceipient() == Message.WIFE) {
    System.out.println(&amp;quot;Wife hears: &amp;quot; + msg.getMessage());
   }
  }
 }
}
&lt;/pre&gt;
&lt;p&gt;As you can see, if there is a message waiting for her, she&amp;#8217;ll hear it, otherwise, she moves on and requests her husband to do something else.&lt;/p&gt;
&lt;p&gt;Lastly, everything is coordinated by a simple driver class containing a &lt;code&gt;main&lt;/code&gt; method like so:&lt;/p&gt;
&lt;pre class="brush: java;"&gt;
import kilim.Mailbox;
import kilim.Task;

public class HoneyDo {

 public static void main(String[] args) {

  Mailbox&amp;lt;Message&amp;gt; sharedMailbox = new Mailbox&amp;lt;Message&amp;gt;();

  Task wife = new Wife(sharedMailbox);
  Task husband = new Husband(sharedMailbox);

  husband.start();
  wife.start();
 }
}
&lt;/pre&gt;
&lt;p&gt;Note how a &lt;code&gt;Mailbox&lt;/code&gt; instance is created for my custom &lt;code&gt;Message&lt;/code&gt; type; what&amp;#8217;s more, the &lt;code&gt;sharedMailbox&lt;/code&gt; is then shared between both the &lt;code&gt;wife&lt;/code&gt; and &lt;code&gt;husband&lt;/code&gt; instances. Lastly, things are started via the &lt;code&gt;start&lt;/code&gt; method. &lt;/p&gt;
&lt;p&gt;Running this hip example yields the following output (remember, your exact output will most likely look different; however, the logic sequence of activities will line up. That is, the wife requests things be done and the husband responds with &amp;#8220;yes, dear&amp;#8221;, which the wife hears). &lt;/p&gt;
&lt;pre class="brush: plain;"&gt;
 Husband listening...
 Husband hears: Please do x, y, and z today, husband.
 Husband says: Yes, dear
 Husband listening...
 Wife hears: Yes, dear
 Husband hears: Please do x, y, and z today, husband.
 Husband says: Yes, dear
 Husband listening...
 Wife hears: Yes, dear
 Husband hears: Please do x, y, and z today, husband.
 Husband says: Yes, dear
 Wife hears: Yes, dear
 Husband listening...
 Husband hears: Please do x, y, and z today, husband.
 Husband says: Yes, dear
 Husband listening...
 Wife hears: Yes, dear
 Husband hears: Please do x, y, and z today, husband.
 Husband says: Yes, dear
 Wife hears: Yes, dear
 Husband listening...
 Husband hears: Please do x, y, and z today, husband.
 Husband says: Yes, dear
&lt;/pre&gt;
&lt;p&gt;The actor model facilitates &lt;a href="http://thediscoblog.com/2008/10/19/poll-which-language-is-better-suited-for-jvm-concurrency/"&gt;concurrent programming&lt;/a&gt; by allowing a safer mechanism for message passing between processes (or actors). Implementations of this model vary between languages and frameworks &amp;#8212; I suggest checking out &lt;a href="http://thediscoblog.com/2008/10/19/book-review-programming-erlang/"&gt;Erlang&lt;/a&gt;&amp;#8217;s actors followed by &lt;a href="http://thediscoblog.com/2009/12/10/book-review-programming-scala/"&gt;Scala&lt;/a&gt;&amp;#8217;s as each implementation is quite neat given their respective syntax. &lt;/p&gt;
&lt;p&gt;In the end, if you want to leverage plain Jane Java &lt;a href="http://en.wikipedia.org/wiki/Actor_model"&gt;actors&lt;/a&gt;, then have a look at &lt;a href="http://www.malhar.net/sriram/kilim/"&gt;Kilim&lt;/a&gt; (or one of the other frameworks available)  &amp;#8212; just make sure you&amp;#8217;ve finished your honey do list first, man.&lt;/p&gt;
                                 &lt;p&gt;&lt;center&gt;Looking to spin up Continuous Integration &lt;em&gt;quickly&lt;/em&gt;? Check out &lt;a href="http://www.ciinabox.com"&gt;www.ciinabox.com&lt;/a&gt;.&lt;/center&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 10 Mar 2010 09:56:00 CST</pubDate>
      <guid isPermaLink="true">http://thediscoblog.com/?p=1069</guid>
      <dc:creator>Andrew Glover</dc:creator>
    </item>
    <item>
      <title>Another Good Tidbit from GOOSGBT</title>
      <link>http://www.nofluffjuststuff.com/blog/james_carr/2010/03/another_good_tidbit_from_goosgbt</link>
      <description>&lt;p&gt;I&amp;#8217;m currently in chapter 12 of &lt;a href="http://www.growing-object-oriented-software.com/"&gt;Growing Object Oriented Software Guided By Tests&lt;/a&gt; and thought I&amp;#8217;d share another good tidbit from one of the asides:&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3&gt;Put Tests in a Different Package&lt;/h3&gt;
&lt;p&gt;We&amp;#8217;ve adopted a habit of putting tests in a different package from the code they&amp;#8217;re exercising. We want to make sure we&amp;#8217;re driving the code through its public interfaces, like any other client, rather than opening up a package-scoped back door for testing.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Good point! Almost everytime I&amp;#8217;ve found my self expose a method that should be private as protected or default it&amp;#8217;s been because that method was really in gross violation of Single Responsibility Principle and I&amp;#8217;ve often taken such code and extracted it to a separate object.&lt;/p&gt;
&lt;p&gt;Thoughts?&lt;/p&gt;</description>
      <pubDate>Tue, 09 Mar 2010 08:37:00 CST</pubDate>
      <guid isPermaLink="true">http://blog.james-carr.org/?p=731</guid>
      <dc:creator>James Carr</dc:creator>
    </item>
    <item>
      <title>Java Champion</title>
      <link>http://www.nofluffjuststuff.com/blog/howard_lewis_ship/2010/03/java_champion</link>
      <description>&lt;p&gt;You might call it petty, you might call it vain, but I've aspired to be recognized as a Java Champion for the last couple of years. The process by which you are selected for this is a bit secretive, but I've finally &lt;a href="https://java-champions.dev.java.net/content/corechampions.html#Ship"&gt;gotten the nod&lt;/a&gt; and joined the roster. 

&lt;p&gt;
My larger goal for Tapestry has always been to create a web application platform so compelling that it would draw developers to the Java programming language, just to be able to use it. Of course, that's not so much a goal as it is a journey. Technologically, I think Tapestry has the chops to embrace that goal (or journey) ... and looking at current discussions and developments in the Tapestry world, I think the other critical areas where Tapestry is lagging (namely, Documentation and Marketing) may come around.

&lt;p&gt;
Want to do your part?  Blog about Tapestry ... what you like, what you don't like, what's missing, and what's hidden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-8860140314474342522?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/yxxLSudkCuU" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 08 Mar 2010 18:39:48 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-8860140314474342522</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>ESDC 2010 resources</title>
      <link>http://www.nofluffjuststuff.com/blog/andrew_glover/2010/03/esdc_2010_resources</link>
      <description>&lt;p&gt;I recently had the opportunity to present four different talks at the &lt;A HREF="http://thediscoblog.com/2010/01/19/development-2-0-concepts-at-esdc/"&gt;Enterprise Software Development Conference&lt;/A&gt; (or ESDC) in San Mateo, California. In an effort to provide additional data points and information, I created individual resource pages for each talk. These pages (hosted at my company&amp;#8217;s site &amp;#8212; &lt;A HREF="http://beacon50.com/"&gt;beacon50.com&lt;/A&gt;) provide links to articles, blog entries, tutorials, and a copy of each presentation. If you&amp;#8217;re curious to see what you missed at ESDC, then have a look, man:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;A HREF="http://beacon50.com/resources/esdc/gtrench.html"&gt;Resources for Groovy from the trenches&lt;/A&gt;&lt;/li&gt;
&lt;li&gt;&lt;A HREF="http://beacon50.com/resources/esdc/easyb.html"&gt;Resources for Easy BDD with easyb&lt;/A&gt;&lt;/li&gt;
&lt;li&gt;&lt;A HREF="http://beacon50.com/resources/esdc/cloud.html"&gt;Resources for Comparing the cloud: GAE versus EC2&lt;/A&gt;&lt;/li&gt;
&lt;li&gt;&lt;A HREF="http://beacon50.com/resources/esdc/rest.html"&gt;Resources for RESTful web services in Grails&lt;/A&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to everyone who came to ESDC and attended my talks &amp;#8212; I had a great time discussing these topics (and more!) with you! &lt;/p&gt;
                                 &lt;p&gt;&lt;center&gt;Looking to spin up Continuous Integration &lt;em&gt;quickly&lt;/em&gt;? Check out &lt;a href="http://www.ciinabox.com"&gt;www.ciinabox.com&lt;/a&gt;.&lt;/center&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 08 Mar 2010 12:48:00 CST</pubDate>
      <guid isPermaLink="true">http://thediscoblog.com/?p=1090</guid>
      <dc:creator>Andrew Glover</dc:creator>
    </item>
    <item>
      <title>Mockito 1.8.3 Released</title>
      <link>http://www.nofluffjuststuff.com/blog/james_carr/2010/03/mockito_1_8_3_released</link>
      <description>&lt;p&gt;&lt;a href="http://monkeyisland.pl/"&gt;Szczepan&lt;/a&gt; has announced on the Mockito user mailing list that 1.8.3 of Mockito has been released. This released includes several small (but useful) additions as well as bug fixes.&lt;/p&gt;
&lt;p&gt;The two parts of this release I like are the &lt;a href="http://mockito.googlecode.com/svn/tags/1.8.3/javadoc/org/mockito/Mockito.html#21"&gt;new annotations&lt;/a&gt; @Spy, @Captor, and @injectMocks. These add to the already useful @Mock annotation to simplify test setup tremendously. Additionally, the @Mock annotation is now configurable so you can add different Mock/Stub styles; previously @Mock only supported the default mock behavior, now you can configure it to RETURNS_MOCKS, CALLS_REAL_METHODS, etc.&lt;/p&gt;
&lt;p&gt;This release also includes a &lt;a href="http://code.google.com/p/mockito/issues/detail?id=170&amp;#038;can=1&amp;#038;q=label:Milestone-Release1.8.3"&gt;feature&lt;/a&gt; I requested that can be useful when trying to get legacy code under test, something I call &lt;a href="http://mockito.googlecode.com/svn/tags/1.8.3/javadoc/org/mockito/Mockito.html#RETURNS_DEEP_STUBS"&gt;deep stubs&lt;/a&gt;. Ever been in the situation where you have code with something like this in the middle of it:&lt;/p&gt;
&lt;pre name="code" class="java"&gt;
someCollaborator.getFoo().doBarThings().getBaz().execute().processResult();
&lt;/pre&gt;
&lt;p&gt;Normally to stub this call, you&amp;#8217;ll have to mock every object returned by each method call, and then stub the last one. Examples for code like this can be a little verbose, but now you can just @Mock the aggregate root and do something like:&lt;/p&gt;
&lt;pre name="code" class="java"&gt;
given(someColllaborator.getFoo().doBarThings().getBaz().execute().processResult).willReturn(resultObject);
&lt;/pre&gt;
&lt;p&gt;Just remember friends, this is only good for legacy code&amp;#8230; if you are already writing your code exemplar first to drive your design, you should know better than to make your object know too many details about it&amp;#8217;s neighbors. &lt;img src='http://blog.james-carr.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;p&gt;This release also includes a &lt;a href="http://code.google.com/p/mockito/issues/detail?id=109&amp;#038;can=1&amp;#038;q=label:Milestone-Release1.8.3"&gt;patch I submitted&lt;/a&gt; to stop having all of the examples in a test run when trying to run a single one in eclipse and intelliJ when using MockitoJunitRunner. &lt;/p&gt;
&lt;p&gt;For a complete list of features/fixes, see the &lt;a href="http://code.google.com/p/mockito/issues/list?can=1&amp;#038;q=label:Milestone-Release1.8.3&amp;#038;colspec=ID+Type+Status+Priority+Milestone+Owner+Summary&amp;#038;cells=tiles"&gt;release notes&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Sun, 07 Mar 2010 22:14:00 CST</pubDate>
      <guid isPermaLink="true">http://blog.james-carr.org/?p=726</guid>
      <dc:creator>James Carr</dc:creator>
    </item>
    <item>
      <title>Scala: Post-Functional, Post-Modern, or Just Perl++?</title>
      <link>http://www.nofluffjuststuff.com/blog/robert_fischer/2010/03/scala_post_functional_post_modern_or_just_perl__</link>
      <description>&lt;h3&gt;Let&amp;#8217;s start with some background.&lt;/h3&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/scala-not-functional/"&gt;I complained that Scala did not seem to be very functional to me&lt;/a&gt;, but I didn&amp;#8217;t really know how best to express what was fundamentally wrong with it. I did know that if &lt;a rel="nofollow" target="_blank" href="http://www.artima.com/scalazine/articles/goals_of_scala.html"&gt;&amp;#8220;functional languages have a fixed set of features&amp;#8221; like Scala&amp;#8217;s creator, Odersky, claims&lt;/a&gt;, then it wasn&amp;#8217;t simply &amp;#8220;first-class functions in there, function literals, closures&amp;#8221;, &amp;#8220;types, generics, [and] pattern matching&amp;#8221;. Scala has missed the functional boat in some basic way.&lt;/p&gt;
&lt;p&gt;After a kerfuffle in the comments, &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/what-is-a-functional-programming-language/"&gt;Brian enlightened us all by telling us what is a functional programming language&lt;/a&gt;. His explanation (while being a self-admitted generalization) is summarized as follows:&lt;br /&gt;
&lt;blockquote&gt;So, what is it that differentiates the functional programming languages from all the other programming languages? It is simply this: the functional programming languages use, as their fundamental model of computation, the lambda calculus, while all the other programming languages use the Turing machine as their fundamental model of computation.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Six months later, &lt;a rel="nofollow" target="_blank" href="http://www.scala-lang.org/node/4960"&gt;Odersky responds with a very interesting post&lt;/a&gt;, which actually agrees that Scala is not a functional language in Brian&amp;#8217;s sense, but instead argues that any language is functional if it &amp;#8220;makes programming centered around functions easy and natural&amp;#8221;. He then runs through a list of features which is in common with functional languages, noting that Scala has them within handwave enough (more on that later). He ends wishing that people would &amp;#8220;stop thinking of functional programming as a different, novel, or exotic way to code&amp;#8221;. Even more, though, Scala is apparently &amp;#8220;an early example of a new breed of postfunctional languages&amp;#8221;.&lt;/p&gt;
&lt;h3&gt;And that gets us to this blog post.&lt;/h3&gt;
&lt;p&gt;First of all, Odersky is still missing the point. It&amp;#8217;s not about whether you use &lt;code&gt;fold&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, and &lt;code&gt;iter&lt;/code&gt;, or whether you can write closures easily. It&amp;#8217;s not even really about pure functions vs. side-effects. To code in a functional style is a fundamentally different way of thinking about problems: instead of thinking about problems as nouns that are doing things, functional programming views a problem as a series of transformations to the world which results in an answer. This is why functional programming is considered &amp;#8220;a different, novel, or exotic way to code&amp;#8221;: it &lt;em&gt;is&lt;/em&gt; a different, novel, and (as of yet) exotic way to code. It&amp;#8217;s as different, novel, and exotic from OO as OO was from procedural. It&amp;#8217;s a different way of thinking about the entire issue. You can &lt;a rel="nofollow" target="_blank" href="http://itmmetelko.com/blog/2008/02/23/functional-programming-immutable-objects-explained-irc-style/"&gt;check out this snippet of an IRC conversation from #ocaml&lt;/a&gt; for more on that.&lt;/p&gt;
&lt;p&gt;The paragon of this way of programming is &lt;a rel="nofollow" target="_blank" href="http://buffered.io/2009/06/27/point-free-style-what-is-it-good-for/"&gt;point-free programming&lt;/a&gt;, where you are quite literally building up a mega-function that describes how your program works, and then executing that one, single function when you run that program. If your language doesn&amp;#8217;t lead people to re-discover point free programming at least in the small, then the language really isn&amp;#8217;t taking function manipulation and functional language type conceptions seriously. And that&amp;#8217;s the case with Scala: even Odersky admits that in Scala, &amp;#8220;currying is more verbose and much less used than in other functional languages&amp;#8221;. (Protip to Scala people: If one of the fundamental stunts of a style is pervasive in all the code but yours, you&amp;#8217;re not in the same style of programming.)&lt;/p&gt;
&lt;p&gt;What really gets me, though, is the claim that Scala is &amp;#8220;an early example of a new breed of postfunctional languages&amp;#8221;, because aside from the static typing, all the language features that Odersky trots out already exist in Perl. It&amp;#8217;s hard to be a vanguard of a new breed of programming languages when there&amp;#8217;s prior art &lt;a rel="nofollow" target="_blank" href="http://history.perl.org/PerlTimeline.html#1980s"&gt;from the 1980s&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t believe me? &lt;a rel="nofollow" target="_blank" href="http://www.amazon.com/exec/obidos/ASIN/1558607013/lovespiralsof-20"&gt;The existence of a book on the topic unconvincing&lt;/a&gt;? Then let&amp;#8217;s run the list of functional language features from Odersky.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Functions as first class values: &lt;em&gt;check&lt;/em&gt;. &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color:#000000;font-weight:bold;"&gt;sub&lt;/span&gt; apply&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#339933;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;$)&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#666666;font-style:italic;"&gt;# Take a function as an argument no problem&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color:#339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
&lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color:#000000;font-weight:bold;"&gt;sub&lt;/span&gt; times2&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;$)&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#666666;font-style:italic;"&gt;# Create a function to take&lt;/span&gt; &lt;span style="color:#000066;"&gt;print&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color:#339933;"&gt;*&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;2&lt;/span&gt; &lt;span style="color:#339933;"&gt;.&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"&lt;span style="color:#000099;font-weight:bold;"&gt;&amp;#92;n&lt;/span&gt;"&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
&lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
apply&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;#92;&amp;amp;times2&lt;/span&gt;&lt;span style="color:#339933;"&gt;,&lt;/span&gt; &lt;span style="color:#cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;/li&gt;
&lt;li&gt;Convenient closure syntax: &lt;em&gt;check&lt;/em&gt; &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color:#b1b100;"&gt;my&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$x&lt;/span&gt; &lt;span style="color:#339933;"&gt;=&lt;/span&gt; &lt;span style="color:#cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
apply &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#000066;"&gt;print&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;*$x&lt;/span&gt; &lt;span style="color:#339933;"&gt;.&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"&lt;span style="color:#000099;font-weight:bold;"&gt;&amp;#92;n&lt;/span&gt;"&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt; &lt;span style="color:#cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color:#b1b100;"&gt;my&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$times_x&lt;/span&gt; &lt;span style="color:#339933;"&gt;=&lt;/span&gt; &lt;span style="color:#000000;font-weight:bold;"&gt;sub&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;$)&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#000066;"&gt;print&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;*$x&lt;/span&gt; &lt;span style="color:#339933;"&gt;.&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"&lt;span style="color:#000099;font-weight:bold;"&gt;&amp;#92;n&lt;/span&gt;"&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
&lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;$times_x&lt;/span&gt;&lt;span style="color:#339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;/li&gt;
&lt;li&gt;List comprehensions: &lt;em&gt;check&lt;/em&gt;. (See &lt;a rel="nofollow" target="_blank" href="http://perldoc.perl.org/index-functions-by-cat.html#Functions-for-list-data"&gt;perlfunc on list data&lt;/a&gt;.)
&lt;/li&gt;
&lt;li&gt;&amp;#8220;Curried&amp;#8221; function definitions and applications: check-ish.&lt;br /&gt;
Okay, so calling this a &amp;#8220;check&amp;#8221; on Scala is a bit of a reach (&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/scala-not-functional/#currying"&gt;cite&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/scala-not-functional/#comment-35168"&gt;cite&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/scala-not-functional/#comment-35550"&gt;cite&lt;/a&gt;, although &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/scala-not-functional/#comment-35231"&gt;note this&lt;/a&gt;—&lt;a rel="nofollow" target="_blank" href="http://www.codecommit.com/blog/scala/function-currying-in-scala"&gt;here&lt;/a&gt; is a more sympathetic run-down on Scala currying). Ignoring the &lt;code&gt;foo(2,_:Int)&lt;/code&gt; syntax for a moment, we can implement basically the same style of &amp;#8220;&amp;#8216;curried&amp;#8217; function definitions&amp;#8221; such as Scala&amp;#8217;s &lt;a rel="nofollow" target="_blank" href="http://www.scala-lang.org/docu/files/api/scala/List.html#foldLeft%28B%29"&gt;List#foldLeft&lt;/a&gt;. &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color:#000000;font-weight:bold;"&gt;sub&lt;/span&gt; add &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#b1b100;"&gt;my&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$x&lt;/span&gt; &lt;span style="color:#339933;"&gt;=&lt;/span&gt; &lt;span style="color:#000066;"&gt;shift&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt; &lt;span style="color:#000066;"&gt;return&lt;/span&gt; &lt;span style="color:#000000;font-weight:bold;"&gt;sub&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$x&lt;/span&gt; &lt;span style="color:#339933;"&gt;+&lt;/span&gt; &lt;span style="color:#000066;"&gt;shift&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
&lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt;
add&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color:#339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt; &lt;span style="color:#666666;font-style:italic;"&gt;# Okay, so you do need an extra -&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;In the case of our &lt;code&gt;apply&lt;/code&gt; function above (where we take a function as the first argument), it&amp;#8217;s even easier.&lt;/p&gt; &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;apply &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#000066;"&gt;print&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;*$x&lt;/span&gt; &lt;span style="color:#339933;"&gt;.&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"&lt;span style="color:#000099;font-weight:bold;"&gt;&amp;#92;n&lt;/span&gt;"&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt; &lt;span style="color:#cc66cc;"&gt;8&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;Now, there isn&amp;#8217;t really argument skipping (i.e.: &lt;code&gt;foo(_:Int,3)&lt;/code&gt;) as a syntax feature, and there isn&amp;#8217;t a built-in &lt;code&gt;curry&lt;/code&gt; function, but if you want Scala&amp;#8217;s &lt;code&gt;Function.curried&lt;/code&gt; in perl, here it is:&lt;/p&gt; &lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color:#666666;font-style:italic;"&gt;# This code released under Creative Commons 0 and WTFPL.&lt;/span&gt;
&lt;span style="color:#000000;font-weight:bold;"&gt;sub&lt;/span&gt; curry&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#339933;"&gt;&amp;amp;@&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#b1b100;"&gt;my&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;$f&lt;/span&gt;&lt;span style="color:#339933;"&gt;,&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;@args&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#339933;"&gt;=&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;@_&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt; &lt;span style="color:#000066;"&gt;return&lt;/span&gt; &lt;span style="color:#000000;font-weight:bold;"&gt;sub&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$f&lt;/span&gt;&lt;span style="color:#339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;@args&lt;/span&gt;&lt;span style="color:#339933;"&gt;,&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;@_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
&lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color:#000000;font-weight:bold;"&gt;sub&lt;/span&gt; add&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;$$&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#000066;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color:#339933;"&gt;+&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;
&lt;span style="color:#009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color:#b1b100;"&gt;my&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$curried&lt;/span&gt; &lt;span style="color:#339933;"&gt;=&lt;/span&gt; curry&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;#92;&amp;amp;add&lt;/span&gt;&lt;span style="color:#339933;"&gt;,&lt;/span&gt; &lt;span style="color:#cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt; &lt;span style="color:#000066;"&gt;print&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;$curried&lt;/span&gt;&lt;span style="color:#339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color:#009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#339933;"&gt;.&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;"&lt;span style="color:#000099;font-weight:bold;"&gt;&amp;#92;n&lt;/span&gt;"&lt;/span&gt;&lt;span style="color:#339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt; &lt;/li&gt;
&lt;li&gt;Lazy evaluation: &lt;em&gt;check&lt;/em&gt;. See &lt;a rel="nofollow" target="_blank" href="http://search.cpan.org/~jesse/Scalar-Defer-0.23/lib/Scalar/Defer.pm"&gt;Scalar::Defer&lt;/a&gt; for lazy val equivalents and &lt;a rel="nofollow" target="_blank" href="http://search.cpan.org/~genie/Tie-LazyList-0.05/LazyList.pm"&gt;Tie::LazyList&lt;/a&gt; for lazy seq equivalents. People generally use a &lt;a rel="nofollow" target="_blank" href="http://www.perldesignpatterns.com/?LazyEvaluation"&gt;double-return approach&lt;/a&gt; for generators (which I realize are different than lazy seqs and only kinda-sorta lazy).
&lt;/li&gt;
&lt;li&gt;Pattern matching: &lt;em&gt;check&lt;/em&gt; (okay, check-ish). See &lt;a rel="nofollow" target="_blank" href="http://perldoc.perl.org/Switch.html"&gt;Switch&lt;/a&gt;. The decomposition isn&amp;#8217;t there, which is the biggest weakness. But the general cumbersomeness and lack of real algebraic data types hamstrings the coolest parts of pattern matching anyway, so I&amp;#8217;m calling it a draw. (This should be read as a generous and sympathetic ruling for Scala: Cedric Beust, for instance, rails against pattern matching/case classes and says &amp;#8220;&lt;a rel="nofollow" target="_blank" href="http://beust.com/weblog2/archives/000490.html"&gt;it&amp;#8217;s hard for me to see case classes as anything but a failure&lt;/a&gt;&amp;#8220;.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, perl&amp;#8217;s got a few features in its favor for functional programming, like more flexible arguments, &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Autovivification"&gt;autovificiation&lt;/a&gt;, list/argument coercion, and dynamic symbol table mangling. Since perl also has OO capabilities, perl is &lt;em&gt;at least&lt;/em&gt; as convincing a &amp;#8220;post-functional language&amp;#8221; as Scala. But there&amp;#8217;s even more in common between the two than that.&lt;/p&gt;
&lt;p&gt;Odersky&amp;#8217;s &amp;#8220;post-functional language&amp;#8221; is really a subtype of &lt;a rel="nofollow" target="_blank" href="http://www.wall.org/~larry/pm.html"&gt;Larry Wall&amp;#8217;s &amp;#8220;post-modern language&amp;#8221;&lt;/a&gt;: it&amp;#8217;s an attempt to create a language that is a grab-bag of multiple paradigms. And when you do that, you&amp;#8217;re just begging for the complaints that you hear leveled against both perl and Scala: it&amp;#8217;s too complicated, its syntax is weird, it&amp;#8217;s too magical, people write in entirely distinct subsets of the language, etc. (&lt;a rel="nofollow" target="_blank" href="http://creativekarma.com/ee.php/weblog/comments/my_verdict_on_the_scala_language/"&gt;cite&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://www.weiqigao.com/blog/2008/03/24/scala_still_uncomfortable_after_five_years.html"&gt;cite&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://neopythonic.blogspot.com/2008/11/scala.html"&gt;cite&lt;/a&gt;) Now, those who master the language (or master their favorite subset of it) love the &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/There's_more_than_one_way_to_do_it"&gt;TIMTOWTDI&lt;/a&gt; aspect. But it also means that the language is left as a jack-of-all-trades, master of none. Yes, Scala and perl integrate a lot of powerful tools from functional languages—but learning OCaml still blew my mind, despite knowing perl for years. As I started off saying, Scala is not a functional programming language. It is a statically typed object oriented language with closures.&lt;/p&gt;
&lt;p&gt;Now, there is a sense in which Odersky is really onto something. The world of programming is forever transformed with closures and list comprehensions as being mandatory for new high-level languages, even if they&amp;#8217;re otherwise object oriented. And software developers are going to need how to work with them effectively if they want to read code moving forward. Yes, after 20+ years, the rest of the programming world finally caught up to one of perl&amp;#8217;s fundamental insights.&lt;/p&gt;
&lt;hr /&gt;&lt;h2&gt;Comments&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37346"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://blog.barrkel.com/' class='url'&gt;Barry Kelly&lt;/a&gt; wrote: Functional programming optimizes for different things than OO does. That means for different problems, you want to take different approaches, depending on your level of familiarity with the problem domain and the solution strategies. And thus for a language that supports both paradigms, different people will often end up using different subsets of the language. But I don't think this is necessarily a damning criticism. Our problems are bigger and more compositional. We need languages that have the semantic richness to support different solution strategies. An example. There's an isomorphism between OO polymorphism / dynamic dispatch, and algebraic data types / pattern matching and destructuring. OO lets you add subclasses as late as dynamically at runtime. ADT lets you add functions freely, and such functions are more composable that they're dealing with well-defined quantities. More generally, OO is about defining loosely bound protocols, while FP is more about flexibly defining transformations over tightly defined structures. But if you want to write a solution that's natural for one paradigm in the other, you end up re-inventing and poorly reinventing the other paradigm. In a comment somewhere else out in the ether, I made an argument that getting FP to work as well as a dynamically typed late bound language like Ruby for fast-iterating web solutions that join together multiple independently developed and fast-iterating modules, you'd end up writing what amounted to a dynamic language just to avoid the brittleness that comes from the over-specification that naturally falls out of static typing. I will agree that e.g. currying is useful, as it decomposes the concept of functions of arbitrary arity into what amounts to a linked list of unary functions; and this is particularly handy for programming in a point-free style. But point-free mostly helps (I would assert) on problems where what you need to do is create an algorithm, where little helpers like fold, map, memoize etc. are your bread and butter. But not all problems are like that, not by a long shot.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37347"&gt;March 7, 2010&lt;/a&gt;, Ittay wrote: "because aside from the static typing, all the language features that Odersky trots out already exist in Perl" That is a big 'aside'. You also forgot that Scala runs on the JVM and Perl not. Not to mention that I think it is common consensus that Perl code is very unreadable. So Scala is a language that combines some FP characteristics with OO, running on the JVM and with a readable (and scalable) syntax. That's a big win for me.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37348"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: I will freely grant that there's a lot to be gained by having some flexibility, but languages that end up trying to play in multiple sandboxes end up either doing one part badly (e.g. OCaml and OO, Scala and functional). The answer seems to be using multiple languages for different contexts, not trying to create the One True Language with all the features of the world in it. That's why when I encounter a programming problem, I will generally reach for perl, Groovy, or OCaml/F#: which one I go for depends on the nature of the problem. But I don't long for a day when there's a language that has all the features of perl, Groovy, and OCaml, because they're fundamentally incompatible takes on the process of programming. The strongly opinionated natures of these languages is precisely what makes them so good. Scala's lack of strong opinions is what's frustrating me. Well, that and having to explain to Java devs over and over again at No Fluff events that learning Scala does not mean learning to program in a functional style. I mean, you &lt;em&gt;can&lt;/em&gt; code Scala in a functional style, but &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/this-is-your-brain-this-is-your-brain-on-ocaml/"&gt;I can code Java in a functional style&lt;/a&gt;. And yes, it's a &lt;em&gt;bit&lt;/em&gt; easier to code in a functional style in Scala, but learning Scala is no more learning functional programming than learning perl is learning functional programming.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37349"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: The "readable (and scalable) syntax" bit is a big assumption—at least to my ear, there's as much concern about the readability of Scala code as there is about perl code. And how much Scala's static typing really helps vs. how much it gets in the way is a matter of contention. But both of those are an aside. The purpose of this post was not to say that people should stop coding Scala and start coding perl: if you're still futzing around in Java-land, Scala (like Groovy and JRuby) is a productivity huge win that can leverage your existing infrastructure. Groovy's probably the semantically closest, JRuby's the conceptually cleanest, and Scala keeps the fetishized complexity and the BDSM aspects of Java. No, this wasn't a call to go back to perl. The purpose of this post is to show that the idea of merging closures with imperative isn't a new idea, and that Scala is no more a functional language than those languages (like perl) which merged the concepts beforehand.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37351"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.illegalargument.com' class='url'&gt;Richard Vowles&lt;/a&gt; wrote: I've been saying this for 6 months at least now - Scala and Perl have way more in common than Scala has in common with any other language. Including a tendency towards unreadability.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37352"&gt;March 7, 2010&lt;/a&gt;, Marc wrote: "It’s as different, novel, and exotic from OO as OO was from imperative." OO is as imperative, if not more so, than C. I assume you meant procedural? Also, there is nothing new in programming languages, period. Everything you see in "new" languages was figured out at least 20 years ago. So, all language designers are just mixing and matching as they see fit. So it's unfair to single out Scala in this regard. While you're at it, go after Groovy, Clojure, Boo, F#, etc.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37353"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.cirrusmachina.com/' class='url'&gt;Nick Bauman&lt;/a&gt; wrote: I find the description "combines some FP characteristics with OO" problematic when discussing hybrid Functional / OO languages. The more I use one of my favorites of these languages, Python, the more I find the OO aspects receding into the background and the functional ones coming to the fore. It seems to me that &lt;b&gt;Functional is OO "done right"&lt;/b&gt; where when I do use OO in them, it's not as heavyweight and seems more natural. I think the key is that in most traditional OO languages the concept of what a type is tends to be much narrower. Can you confirm this in your experience?&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37354"&gt;March 7, 2010&lt;/a&gt;, Thomas Heywood wrote: Robert, I admire your ability to "professionally blog." You delivered no useful content, but you did it with inspiring attention to page hits and comment controversy. Yes, Scala is a multiparadigm language. Yes, Perl is one too. Yes, they both share features from Common Lisp. That's not really worth my or your time. But you cleverly used the confrontational tone to make the blatant non-issue into a controversial &lt;i&gt;issue&lt;/i&gt;. You cleverly used Blogosphere's beloved "Scala" and "Perl" tags in a &lt;i&gt;single&lt;/i&gt; article. You nagged about a minor syntax issue like it was life-or-death as only a true master-of-functional-programming-who-blogs-more-than-he-actually-programs can. Bob, you're my hero - a true &lt;i&gt;Dilbert's&lt;/i&gt; Wally in flesh. A guy without any real code to show - but who "realigns the tone of existing projects" and whose "technical leadership focuses on pragmatic communication" like there's no tomorrow. Wally - sorry, Robert - do you think you could write some posts on how to professionally sell bull and call it "technical accomplishments?" Many of us CompSci majors would like to get in on this money for nothing scheme. Unless, of course, you're not comfortable writing about things you actually do know a little about.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37355"&gt;March 7, 2010&lt;/a&gt;, Nilanjan Raychaudhuri wrote: Well I believe it is possible to write unreadable code in any language and I am not sure blaming any programming language for that is a good idea.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37356"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.codecommit.com/blog' class='url'&gt;Daniel Spiewak&lt;/a&gt; wrote: Throwing out static typing fundamentally changes what Scala has to offer. In a sense, I agree with you that if we completely threw out Scala's type system (and &lt;i&gt;all&lt;/i&gt; that it entails), then we would end up with a language which improves very little (if at all) over languages like Perl or Ruby. However, that first step is a doozy and not really fair. Consider a snippet like this: &lt;pre lang="scala"&gt;"123".to[Int] // =&amp;gt; 123
".+".to[Regexp] // =&amp;gt; /.+/
true.to[Regexp] // compile error!&lt;/pre&gt; There's a lot of magic going on here, all of which is made possible by the static type system. In fact, while this sort of thing is *possible* in a dynamic language with open classes (like Ruby), the implementation will be ugly, unscoped, brittle and difficult to extend. In Scala, the implementation looks something like this: &lt;pre lang="scala"&gt;trait Converter[-A, +B] { def apply(a: A): B
} implicit object StringToInt extends Converter[String, Int] { def apply(str: String) = str.toInt
} implicit object StringToRegexp extends Converter[String, Regexp] { def apply(str: String) = Regexp(str)
} implicit def toSyntax[A](a: A)= new { def to[B](implicit conv: Converter[A, B]) = conv(a)
}&lt;/pre&gt; This is taking advantage of a feature which Scala inherits from Haskell called &lt;i&gt;typeclasses&lt;/i&gt;. This is an feature which is inherently tied to static typing and is often very difficult to emulate in dynamic, so-called "more flexible" languages. The real magic of this is two-fold. First, it's scoped, and so we actually have to import these members before they start messing with our objects. It's hard to over-state how important this is to keeping such extensions from devolving into intractable monkey-patching. Second, it's extremely extensible. What if we want to add another conversion from Foo to Bar? Just define it ourselves as an implicit value in scope! Or, if we &lt;i&gt;don't&lt;/i&gt; want the implicit syntax, we can always specify the conversion explicitly: &lt;pre lang="scala"&gt;// off in *our* code, separate from the converter lib
implicit object StringToBool extends Converter[String, Boolean] { def apply(str: String) = str.toBoolean
} "true".to[Boolean] // =&amp;gt; true
"false".to(StringToBool) // =&amp;gt; false&lt;/pre&gt; I'm not even going to try to imagine how to do this sort of thing in Perl. Even in Ruby, which usually makes monkey-patching quite simple, the implementation still ends up extremely nasty: &lt;pre lang="ruby"&gt;class Object def to(target) case target when :fixnum if self.class == String self.to_i else raise "Unknown conversion: String -&amp;gt; :fixnum" end # ... end end
end&lt;/pre&gt; ...and, you get the picture. You could probably do this in a nicer way, but it would still end up being fragile, unscoped and virtually impossible to extend. &lt;i&gt;This&lt;/i&gt; is what you're throwing away when you discard the type system, not some unreliable correctness "guarantee". And if I can throw together an example like this in a blog comment in just a few lines of Scala, imagine what can be done in a non-trivial system with real requirements. The type system is an intrinsic part of Scala's power and expresivity. Remove it and you're not even looking at the same language.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37357"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.codecommit.com/blog' class='url'&gt;Daniel Spiewak&lt;/a&gt; wrote: While currying and point-free aren't as syntactically clean as they could be in Scala, they are certainly still used (I use those features all the time). Does this make Scala less "functional" than Haskell or ML? Yeah, probably (I've made that argument in the past). Does it mean that Scala is no more functional than Perl? Absolutely not. Theoretically speaking, currying is possible in &lt;i&gt;any&lt;/i&gt; language which supports closures (alblue, if you're reading, yes I do mean "closure" and not "lambda"). You can even define a curry function in C++, though the obfuscated template mess it entails makes it nigh unreadable. Lambdas ("closures" if you will) and function values do not a functional language make. C has function values, and I don't think anyone who understands the debate will argue that it is "functional". Ruby has function values &lt;i&gt;and&lt;/i&gt; lambdas, but they are fundamentally different constructs and produce different values (just like in Perl). Again, not a functional language (though you can use many patterns which find their roots in FP, like &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;fold&lt;/code&gt;). My point is this: you can't go out of your way to link FP to point-free and lambda calculus and then turn right around and claim that Perl and Scala are in the same league. Scala's unified functions and function values alone should be sufficient to overturn that one.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37358"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Yes, I meant procedural.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37359"&gt;March 7, 2010&lt;/a&gt;, Martin wrote: You really can't claim "perl has had _____ since the 80's" and then point to books about Perl 5. Perl 25 years ago is *very* different than it is now. Your point that Scala and perl are similar is well taken, but I'm not totally clear why this is bad for Scala or Perl. The way Perl 6 is going towards a virtual machine, I wouldn't be surprised to see Perl and Scala and Java running together on a JVM sometime soon.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37360"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: I'm not saying it's bad for either Scala or perl to be similar to each other — on the point of similarity, I'm simply saying that in the ways Odersky argues Scala is "functional", perl is just as functional, and so I'm still unconvinced that Scala deserves to be called a "functional language". You don't hear people listing off the functional languages like: "Haskell, OCaml, perl, Lisp...". So to hear people say "Haskell, OCaml, Scala, Clojure" just gets my goat. I'm also saying that on the point of similarity, it shouldn't be a surprise that we're getting similar unreadability/complexity complaints about Scala as we got about perl, since they are so similar. I heard something about perl getting onto the JVM for AppEngine, but can't find additional info on it.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37361"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: In what ways do Scala's unififed functions and function values outperform perl?&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37362"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Note the point I'm arguing: I'm arguing that Scala is no more a functional language than perl is. Functional languages can be dynamic (e.g. Clojure), so static vs. dynamic typing is irrelevant to the point I'm trying to make.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37363"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: You've earned a special spot in my heart: this is my new favorite flame of all time. I mean, the fact that you say I don't have "any real code to show" just goes to show that you're not paying attention, because you've somehow managed to miss my long trail of open source projects. And you kinda missed the boat on the entire fundamental question: "Is Scala a functional programming language?" But still, the Dilbert references, the accidentally-on-purpose "slip of the keyboard", and the general long-suffering tone is really nicely done. A+&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37364"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Oh, and you're fair on the dating thing. It's hyperbolic to conflate Perl 1 with Perl 5, although I honestly have no idea how far back I can go in perl and still have my code samples work. If you find out, let me know.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37365"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Brian Hurt, the co-blogger here on EnfranchisedMind, is theoretically working on a post about how OO is fundamentally broken. I'll leave that to him. My experience has been that many of the Gang of Four design patterns just aren't relevant anymore, and inheritance is something I'm extremely reluctant to use and much more aware of its difficulties. I'm not sure exactly what it would mean to say that "the concept of what a type is tends to be much narrower", but I certainly have a much thinner type hierarchies in the world of functional programming.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37366"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Oh, not to mention the cite of enterprise-ese from SmokejumperIT.com. I mean, that's some real attention to detail for the zingers. In all seriousness, this is my favorite flame of me of all time. Thanks!&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37367"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.naildrivin5.com/blog' class='url'&gt;Dave&lt;/a&gt; wrote: FWIW, I really dug this post. As to the topic at hand, I'm not even sure what point there is to saying Scala is or isn't "functional". The only real purpose seems to be to make it easy to show how awesome Haskell is by point out Scala's perceived shortcomings as a functional language. For my money, Scala is simply "Java: The Next Generation". A general-purpose, statically-typed, object-oriented language that has broad applicability to many problem domains. Arguing "what is functional" might be a fun exercise, but it's not really going to lead us anywhere; look at most n-tier Java applications: to say they are object oriented would be a vast overstatement. Java is object-oriented in that it's main means of organizing code are around classes and objects (which is exactly the same as in Scala), but most systems still end up using OO only when it helps, and throwing it for imperative/procedural stuff when it makes sense to do so. I would be willing to bet that Scala will be much the same way; the code &lt;b&gt;inside&lt;/b&gt; our classes might be much more functional (simply because its' simply worth-it to do in Scala, whereas it's not terribly so in Java), but I don't see it ushering in some functional utopia (LISP has had, oh, I don't know, &lt;i&gt;the entire history of the field of computer science&lt;/i&gt; to usher this in and largely failed [no offense to LISP]). Scala is an escape route from Java's cruftiness without having to bend your mind or prejudices &lt;b&gt;too&lt;/b&gt; much. Much as Java was to C++.
&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37368"&gt;March 7, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.kaleidic.com' class='url'&gt;Tracy Harms&lt;/a&gt; wrote: The most interesting sentence in your post, to me, was this: &lt;em&gt;If your language doesn’t lead people to re-discover point free programming at least in the small, then the language really isn’t taking function manipulation and functional language type conceptions seriously.&lt;/em&gt; This has me wondering, though, about your agreement with Brian that the key quality is reliance on lambda calculus as the model of computation. Not that I'm convinced we need a "key quality." It just looks to me that the range of languages you have in mind would not be identified through this criterion.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37369"&gt;March 8, 2010&lt;/a&gt;, joe poki wrote: what's up with these groovy people nowadays? groovy++ is 10 trillion times faster than scala actors, now this piece. your rant could be summarized like I Do Not Like Scala. Look, I get that. But I must say it's funny that you use this patronizing tone with Odersky as he was a n00b who has no idea about languages and then once you get a trollish comment, you go on and post it everywhere: OMG somebody was responding to my trollish post in a trollish manner, what a surprise? as for your post:
just because a language can be used in a certain way (or certain language toolsets can be simulated in that language) that does not mean that the users will find that specific style idiomatic. What matters is the style you will meet the most while reading or writing code in that specific language (hack, even java has various functional libraries: lambdaj, functionaljava etc. but how many people would consider code written with these library java-like?). When people say that scala is "kinda functional", what they really mean is that the language is nudging you into that direction (preference for pattern matching, option type, final variables, map, foreach,closures, partial functions etc.). And this nudging towards the functional style is what makes scala "postfunctional". (other features responsible for the "scala feel" but not directly related to the functional thing: static typing w/ type inference, a powerful type system, xml literals, implicit converions, case classes, mixins + various actor libs etc.)&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37370"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: My issue isn't with people saying Scala is "kinda functional". It's saying it's a "functional language". I've heard people say they want to learn Scala b/c then they'll know functional programming, and that's just wrong. Worse, I've heard people write off functional programming because they didn't like Scala. This means that the misconception that Scala is a functional language is hurting &lt;em&gt;real&lt;/em&gt; functional language adoption and hindering people's advancement as software developers by making them think they know functional when they don't. So I'm trying to reinforce the barrier between real functional languages and languages with closures. I'm not particularly knocking Odersky here: what he's done with Scala is pretty impressive. But he's clinging to a title that Scala doesn't deserve. While I appreciate the move with "postfunctional", I'd be a big fan if it also meant he'd give up "functional" — but he's just taking both titles on. In so doing, he's diluting what we mean by a "functional language", and that's just not helpful to anyone involved. The evidence does seem to be that Odersky doesn't really know functional languages. Or, if he does know them, he knows them academically or intellectually, and doesn't really grok them. But you can't be an expert on everything, and I get that. This whole conversation is really kind of sad. There's such an extreme dichotomy here: the assumption seems to be that if you criticize a language, you must hate it. I don't hate Scala: Scala is what Java should be. It's finally a competitor to C# on the JVM — the advanced capabilities of C# have been downright embarrassing for a long time, and Scala evens the playing field. I'm just criticizing the way we talk about this language, and providing counter-evidence to some of the claims made about it.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37371"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Which languages do you see as missing one of the two qualities?&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37372"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: As &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37370"&gt;I will say below&lt;/a&gt;, my issue is mainly one of vocabulary and pedagogy, because I'm frustrated with the murky waters that such marketing-speak has created.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37374"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: &lt;b&gt;PS:&lt;/b&gt; From someone who has been there &lt;i&gt;(remember: I'm a static typing fan, too)&lt;/i&gt;: If you want to debate static typing usefulness vs. dynamic typing usefulness, don't argue that it's hard to implement type safety in a dynamically typed language. It doesn't win you any points with the dynamic language crowd, because they've already accepted they don't need it.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37376"&gt;March 8, 2010&lt;/a&gt;, Peter Lewerin wrote: Daedalus and his son Icarus were imprisoned by King Minos, and made themselves wings out of wax and feathers to escape. Before they took off from the island, Daedalus warned his son not to fly too close to the sun. The sensation of flying made Icarus forget the warning and he soared higher and higher. Eventually the wax melted and he fell into the sea. A programmer can escape the prison of procedural programming using functional programming, but going for the purest form of FP isn't really a sustainable goal. Most likely, these wonktional programmers will melt their wings by straying too close to the realm of mathematics and plunge to their deaths.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37377"&gt;March 8, 2010&lt;/a&gt;, Thomas Heywood wrote: &lt;cite&gt;And you kinda missed the boat on the entire fundamental question: “Is Scala a functional programming language?"&lt;/cite&gt; Scala is a multiparadigm language that supports procedural, functional and object-oriented programming. We've had that since 1950s and Lisp. Now, what was the fundamental question again?&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37378"&gt;March 8, 2010&lt;/a&gt;, Thomas Heywood wrote: (Mea culpa: we've only really had it supplied with the language since 70s, when Lisp machines took off. Still, a blatant fact is blatant, no matter how much you blog it into shape.)&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37379"&gt;March 8, 2010&lt;/a&gt;, Vassil Dichev wrote: Robert, if you like Perl, that's nothing to be ashamed of :-) Seriously, I think your article is thought-provoking, if a little controversial. Still, there are several things I disagree with. First of all, I have interpreted Odersky's article in the spirit of: "OK, I don't insist on calling Scala a functional language". One important piece you didn't mention was immutable data structures. Perl doesn't scale very favorably here. Was this on purpose? I find it important not just what a language *can* do, but also what it *cannot* (easily) do. Mutation and scoping are some of the things Scala restricts rather successfully. I also don't find how the fact that Perl has flexible arguments, autovivificiation, list/argument coercion, and dynamic symbol table mangling makes it more functional. Does Haskell have these? Do you consider Haskell functional? Then I also don't see many people argue that Java is object-oriented. By the same reasoning, it's not- it certainly has types that are not objects, and you can certainly write in a procedural style in Java (unfortunately some people really do). Also, I don't see you arguing that OCaml is not object-oriented, because it's also considered a multi-paradigm language. I see that in one of your comments you agree that OO is poor in OCaml, which is fair enough, but I think some OCaml users wouldn't agree with you on this count either. I most emphatically agree that if you "know" how to write working Scala code, this doesn't mean you know all about functional programming. But I disagree that this harms "real" (read purer) functional languages any more than Java harms "real" object-oriented languages (whatever they are). In the end, I'm also fine with the definition of "statically typed object oriented language with closures".&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37380"&gt;March 8, 2010&lt;/a&gt;, Vassil Dichev wrote: I've just read some of the blog posts you've linked to, and it's quite telling that &lt;a rel="nofollow" target="_blank" href="http://creativekarma.com/ee.php/weblog/comments/my_verdict_on_the_scala_language/"&gt;two&lt;/a&gt; of &lt;a rel="nofollow" target="_blank" href="http://www.weiqigao.com/blog/2008/03/24/scala_still_uncomfortable_after_five_years.html"&gt;them&lt;/a&gt; complain that Scala is &lt;em&gt;too&lt;/em&gt; functional, while you complain that it's not functional &lt;em&gt;enough&lt;/em&gt;. I think this is the problem with Scala: you can't appease everybody without any mental effort on their part to get used to the new style of programming. And I think the same can be said of OCaml. I also think OCaml would be a wonderful language to learn (and I might try it soon).&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37382"&gt;March 8, 2010&lt;/a&gt;, Paul Kaletta wrote: All of your examples should work with any version of Perl 5, which came out in 1994.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37384"&gt;March 8, 2010&lt;/a&gt;, Martin Odersky wrote: Robert: Your blog and even more so your comments make it sound as if I have no clue about what functional programming is. So, it must be because of a series of freak accidents that I organized ICFP, am a member of the IFIP working group on functional programming and am a member of the editorial board of the Journal of Functional Programming. And I even published quite a bit on lambda calculus, too :-). Seriously, I stand completely by my article on postfunctional programming. I believe your post here has added nothing of substance to the discussion. http://www.scala-lang.org/node/4960&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37386"&gt;March 8, 2010&lt;/a&gt;, joe poki wrote: if you cite every single well-known post that dismisses scala one way or another and you go on and say "it’s too complicated, its syntax is weird, it’s too magical, people write in entirely distinct subsets of the language", then people will rightly assume you do not like scala, I do not get it why you are surprised (notice, I did not say you hate it, just that you dislike it). see, the patronizing stuff again "Odersky doesn’t really know functional languages". As I tried to point out: what matters is how a language is used and what's considered idiomatic and in that sense scala definitely has some functional feel to it (and no, it's not just about closures or foreach, but preference for pattern matching, option types, final variables, map, foreach,closures, partial functions etc. etc.).&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37387"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.kaleidic.com' class='url'&gt;Tracy Harms&lt;/a&gt; wrote: To the best of my knowledge, Factor, Joy, FL, and J are languages that favor anonymous arguments (and/or emphasize composition of functions) while lacking reliance on lambda expressions.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37388"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: If you're up for not calling Scala a "functional programming language", tell Odersky.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37389"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: It's not patronizing to say someone doesn't know something, or to disagree with the way someone is using language. That's just not what patronizing speech is. It'd be patronizing if I started explaining to Odersky what closures are and how they're supposed to work, or &lt;a rel="nofollow" target="_blank" href="http://tinyurl.com/yk9nas8"&gt;if I sent you off to look at this link&lt;/a&gt;. &lt;em&gt;That&lt;/em&gt; would be patronizing.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37390"&gt;March 8, 2010&lt;/a&gt;, Thomas Heywood wrote: &lt;cite&gt;Your blog and even more so your comments make it sound as if I have no clue about what functional programming is.&lt;/cite&gt; Martin, hate to break it to you, but all you ever did was bring effective functional programming to a mainstream platform for the benefit of industry and academia. Call me back when you write a wrapper library or two, learn the persistence API of a web framework, or &lt;cite&gt;realign the tone of existing projects.&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37391"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: That's cool that you're so involved. Ultimately, though, our problem is boiling down to one of language. If Scala and perl are functional languages, how do we differentiate them from languages like Haskell, OCaml, and Lisp, where the fundamental way of tackling problems is different? I'd like to use the term "functional programming language" for the latter, and I'm more than happy to stick to "postfunctional programming language" or "multi-paradigm programming language" for the former. But that means we stop calling Scala a functional programming language, as most of the commenters here on the post already have. Deal?&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37392"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Yeah, that's the general issue with these multiparadigm languages like Scala and perl. If OCaml narrowly avoided that fate (and I think it has), it was by completely subjugating the OO aspect to the functional aspect, and not really using the OO aspect much.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37393"&gt;March 8, 2010&lt;/a&gt;, joe poki wrote: If you think saying somebody does not know squat about a subject while that person is supposed to be some sort of an expert on the topic is not condescending, then I do not know what is. By the way, it seems I was not alone, see Odersky's comment above.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37394"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: The immutability is a good point, and it's an area where Scala certainly pulls ahead. Actually, the Ruby (and, to a lesser extent, C#) people regularly say that Java isn't really OO, because a lot of things in Java weren't either objects or messages. I think Ruby inherited that criticism from the old SmallTalk people. And I'll happily argue that OCaml isn't object oriented: while it &lt;em&gt;has&lt;/em&gt; objects, it's certainly not oriented towards them. What harms functional programming languages is when Java people learn Scala and then think they know functional programming languages. Or, worse, when they decide they don't like Scala and then conclude they don't like functional programming. This happens &lt;em&gt;a lot&lt;/em&gt; because Scala was lauded as a functional programming language on the JVM which was comfortable for Java people. It's the murkiness in the water that's the issue.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37395"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.codecommit.com/blog' class='url'&gt;Daniel Spiewak&lt;/a&gt; wrote: In Perl, functions and lambdas are fundamentally different. If nothing else, this can be seen by the different invocation syntax. You can convert between functions and lambdas (just like in Ruby and Groovy), but they are very different constructs as far as the language is concerned. To me, one of the essentials of a functional language is that functions are merely lambdas which have been assigned to a named value. OCaml and Haskell encourage this notion with their syntax for function declaration (in fact, Haskell's function decl syntax is &lt;i&gt;exactly&lt;/i&gt; the same as its value decl syntax). Perl doesn't even come close to meeting this qualification. Scala does &lt;i&gt;substantially&lt;/i&gt; better, though I'll admit that it does have its gotchas (methods are sometimes tricky).&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37396"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: While that's a bit hardcore of a comparison (and somewhat damning on people's ability to learn), I definitely agree with your point. And Scala's great in this regard—as I said a number of times, I think Scala is where Java should be if Java's growth hadn't been stunted. If you look at how C# has evolved, Scala's basically right in line with that kind of development. And so a Java developer learning Scala in order to push their way of thinking about types and functions is a great move.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37397"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: True — I'm oversimplifying the world into imperative and functional. There are other paradigms out there (e.g. Factor's stack-based approach) which also can lead to point free programming.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37398"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Do they work before that? (Or, rather, would they work before that if I dumped the prototypes?)&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37399"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: True: there are conversions that need to be made between functions and lambdas in perl. This suggests for Scala (as a multiparadigm language) having a somewhat stronger functional aspect than perl, but it still doesn't make it a functional programming language &lt;i&gt;a la&lt;/i&gt; OCaml and Haskell.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37400"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://aliciaweller.com/' class='url'&gt;Alicia&lt;/a&gt; wrote: Wouldn't it be awesome if you really could make money writing b.s.? People won't even donate a dollar towards valuable open source projects...the suggestion that you could make money for being good at b.s. is hilarious.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37401"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: Amen.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37402"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: True enough. I'm just trying to wrap my head around how Odersky can really grok functional programming and then assert that it's simply bolt-on features of a language. The difference between Haskell and Java is not simply one of syntactic sugar. Claiming he's mistaken about how FP works is actually a generous take—claiming he's clinging to the FP title for Scala for some ulterior reason when he should know better is much less generous. I was trying to give him the benefit of the doubt.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37403"&gt;March 8, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://james-iry.blogspot.com' class='url'&gt;James Iry&lt;/a&gt; wrote: Robert Fischer Finally Admits That Scala Is Functional (http://james-iry.blogspot.com/2010/03/robert-fischer-finally-admits-that.html)&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/post-functional-scala/#comment-37404"&gt;March 8, 2010&lt;/a&gt;, Martin Odersky wrote: Robert, please, read my post again: http://www.scala-lang.org/node/4960 Nowhere did I define functional programming exclusively by a list of features. Instead I had as my central definition: "A functional language makes programming centered around functions easy and natural." A good test of this would be: is it common to write functional programs in the language in question? It's usually far easier to tell whether a program is functional than whether a programming language is functional. By that standard Scala is clearly functional; many of the classes and modules written in it are purely functional and every cool idea from Haskell seems to be implemented sooner or later in Scala (not that we don't invent some cool ideas of our own as well). I don't know Perl well enough to be able to tell whether there are many functional programs written in it, and whether the expression of such programs is easy and natural.</description>
      <pubDate>Sat, 06 Mar 2010 21:30:00 CST</pubDate>
      <guid isPermaLink="true">http://enfranchisedmind.com/blog/?p=2330</guid>
      <dc:creator>Robert Fischer</dc:creator>
    </item>
    <item>
      <title>Free lunches, mousetraps and the Actor model</title>
      <link>http://www.nofluffjuststuff.com/blog/andrew_glover/2010/03/free_lunches_mousetraps_and_the_actor_model</link>
      <description>&lt;p&gt;&lt;img style="PADDING-LEFT: 1.0em; PADDING-RIGHT: 0.0em; PADDING-TOP: 0.0em; FLOAT: RIGHT; PADDING-BOTTOM: 0.0em" src="http://thediscoblog.com/images/2010/freelunch.jpg" alt="free lunch" width="231" height="198"/&gt;A politician once mused &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;A free lunch is only found in mousetraps.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;While this quote is amusing, it&amp;#8217;s painfully true. In fact, the whole notion of a free lunch and its consequences was copacetically captured by Herb Sutter in an article entitled &amp;#8220;&lt;A HREF="http://www.gotw.ca/publications/concurrency-ddj.htm"&gt;The Free Lunch is Over: A Fundamental Turn Toward Concurrency in Software&lt;/A&gt;&amp;#8221; that was published in &lt;A HREF="http://www.ddj.com/"&gt;Dr Dobb&amp;#8217;s Journal&lt;/A&gt; back in 2005. In this well crafted masterpiece, Mr Sutter tore apart the misplaced belief that &lt;A HREF="http://en.wikipedia.org/wiki/Moore%27s_law"&gt;Moore&amp;#8217;s Law&lt;/A&gt; would continue to unleash higher and higher CPU clock speeds and thus he predicted an end of the &amp;#8220;free lunch&amp;#8221; that we&amp;#8217;ve had when it comes to increasing the performance of software applications. That is, clock speeds have roughly stabilized around 3GHz &amp;#8212; and they&amp;#8217;ve held there for a few years now. &lt;/p&gt;
&lt;p&gt;As Mr. Sutter points out&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;the growth [in chip speeds speeds] will come mostly in directions that do not take most current applications along for their customary free ride.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Thus, obtaining an appreciable speed up in application performance requires taking advantage of multi-core chip architectures (where Moore&amp;#8217;s Law has been realized). And to do this, of course, Mr. Sutter advocates &lt;A HREF="http://thediscoblog.com/2008/09/06/concurrency-is-hard-but-does-anyone-care/"&gt;concurrent programming&lt;/A&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;applications will increasingly need to be concurrent if they want to fully exploit CPU throughput gains&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Interestingly, the author concludes with a few points, one of which hits the nail on the head with respect to where the majority of mind share around this subject is focused: &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;we desperately need a higher-level programming model for concurrency than languages offer today&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Indeed, the basic programming model of hip languages like Java is thread based. And while multi-threaded applications aren&amp;#8217;t terribly hard to write &amp;#8212; there are challenging to &lt;I&gt;write correctly&lt;/I&gt;. &lt;/p&gt;
&lt;p&gt;In a paper published in 2006 by Edward A. Lee entitled &amp;#8220;&lt;A HREF="http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf"&gt;The Problem with Threads&lt;/A&gt;&amp;#8220;, the author argues that concurrent programming isn&amp;#8217;t all that hard. In his view, the problem isn&amp;#8217;t with concurrency &amp;#8212; it&amp;#8217;s with the prevailing model: threads. &lt;/p&gt;
&lt;p&gt;As he states: &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The problem is that we have chosen concurrent abstractions that do not even vaguely resemble the concurrency of the physical world&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The author goes on to point out that the inherent non deterministic nature of threads presents a conundrum for developers: &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;a folk definition of insanity is to do the same thing over and over again and to expect the results to be different. By this definition, we in fact require that programmers of multithreaded systems be insane.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Mr. Lee provides an interesting story regarding the challenges and hidden dangers of concurrent programming. He relates an experience where a multi-threaded application that had a strict code review policy in place along with &lt;A HREF="http://thediscoblog.com/2008/12/01/code-coverage-coterie-confab/"&gt;100% code coverage&lt;/A&gt; (note, what type of coverage or how it was obtained wasn&amp;#8217;t disclosed) ran for 4 years without error. Nevertheless, finally the code deadlocked. He goes on to speculate that many &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;multi-threaded general-purpose applications are, in fact, so full of concurrency bugs that as multi-core architectures become commonplace, these bugs will begin to show up as system failures&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;As such, Mr. Lee espouses an alternative to threads: &lt;A HREF="http://en.wikipedia.org/wiki/Actor_model"&gt;actors&lt;/A&gt;. He&amp;#8217;s quick to note that actor-oriented models aren&amp;#8217;t new, but what he does suggest is interesting. He notes that languages that have actors, such as &lt;A HREF="http://thediscoblog.com/2008/10/19/book-review-programming-erlang/"&gt;Erlang&lt;/A&gt;, weren&amp;#8217;t taking root (at the time); thus, he submits:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;We should not replace established languages. We should instead build on them.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Fast forward to today. Java the platform isn&amp;#8217;t dead. It&amp;#8217;s thriving with a multitude of alternate JVM languages &amp;#8212; a few of which embed the actor model (namely &lt;A HREF="http://thediscoblog.com/2009/12/10/book-review-programming-scala/"&gt;Scala&lt;/A&gt;). What&amp;#8217;s more, libraries written in Java and for Java are available, which enable the actor model (such as &lt;A HREF="http://www.malhar.net/sriram/kilim/"&gt;Kilim&lt;/A&gt;). Plus, the Java language itself has started to add more complex features to enable easier concurrent programming. &lt;/p&gt;
&lt;p&gt;So what&amp;#8217;s the lesson in all of this? First, the evolutionary instinct to throw more hardware at a performance problem is now extinct. Programs written today will need to be designed with concurrency in mind. Second, doing this with normal threads is challenging at best. A better, more understandable way is via the actor model, which is available in a number of &lt;A HREF="http://thediscoblog.com/2008/10/19/poll-which-language-is-better-suited-for-jvm-concurrency/"&gt;frameworks&lt;/A&gt; and &lt;A HREF="http://thediscoblog.com/2008/10/31/is-scala-or-clojure-poised-for-stardom/"&gt;alternate languages&lt;/A&gt;. Therefore, learn them today, lest you find yourself snagged by a mousetrap, man.&lt;/p&gt;
                                 &lt;p&gt;&lt;center&gt;Looking to spin up Continuous Integration &lt;em&gt;quickly&lt;/em&gt;? Check out &lt;a href="http://www.ciinabox.com"&gt;www.ciinabox.com&lt;/a&gt;.&lt;/center&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 02 Mar 2010 18:01:00 CST</pubDate>
      <guid isPermaLink="true">http://thediscoblog.com/?p=1061</guid>
      <dc:creator>Andrew Glover</dc:creator>
    </item>
    <item>
      <title>Presenting at Lambda Lounge This Thursday</title>
      <link>http://www.nofluffjuststuff.com/blog/james_carr/2010/03/presenting_at_lambda_lounge_this_thursday</link>
      <description>&lt;p&gt;I&amp;#8217;ll be giving a presentation at &lt;a href="http://lambdalounge.org/"&gt;Lambda Lounge&lt;/a&gt; this Thursday on &lt;em&gt;Behavior Driven Development With Jspec&lt;/em&gt;. If you&amp;#8217;re in the St.Louis area come on by and learn about BDD and how you can use it to drive your design. I&amp;#8217;ll be using &lt;a href="http://jspec.info"&gt;jspec &lt;/a&gt;to demonstrate how to build a functioning feature for a javascript library driven by small, iterative examples.&lt;/p&gt;</description>
      <pubDate>Mon, 01 Mar 2010 11:49:00 CST</pubDate>
      <guid isPermaLink="true">http://blog.james-carr.org/?p=723</guid>
      <dc:creator>James Carr</dc:creator>
    </item>
    <item>
      <title>Retrospective Rules</title>
      <link>http://www.nofluffjuststuff.com/blog/james_carr/2010/02/retrospective_rules</link>
      <description>&lt;p&gt;I&amp;#8217;m gearing up to put together a retrospective for my team at my current client site, and I&amp;#8217;ve been both thinking about and reading over notes from previous retrospectives I&amp;#8217;ve either sat in or facilitated. Looking over a lot of these notes, especially from the worst ones, I&amp;#8217;ve noticed an emerging pattern of behavior that can either make or break a retrospective. Here&amp;#8217;s a few that I think are the most important.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Retrospective Belongs to the Team&lt;/strong&gt;
&lt;p&gt;This is possibly the most important observance I&amp;#8217;ve noticed&amp;#8230; retrospectives are only effective if they truely belong to the team. This means that it should only be attended by the team and only the team can pick a goal and how they&amp;#8217;re going to follow up on them. Management shouldn&amp;#8217;t attend the retrospective imho as they can cause interference, step in, or require metrics to be collected. Several retrospectives I participated in at my previous client had the manager constantly cut people off or tell them that the goal they&amp;#8217;re proposing won&amp;#8217;t work and refuse to let it be considered. These retrospectives were the most useless in my opinion and we never accomplished anything.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;Strong&gt;Don&amp;#8217;t Let It Become a Whine-fest&lt;/strong&gt;
&lt;p&gt;Retrospecting is about inspect and adapt&amp;#8230; about looking at our experiences over the past and using root cause analysis to find causes and how we can improve in the future. However, if there is plenty of negativity in the past, it can be easy to succumb to &amp;#8220;crying over spilt milk&amp;#8221; without coming up with any real solutions. And nothing is worse for a team then to spend an hour in a room listening to each other bicker without any from of constructive activity&amp;#8230; it will leave the team feeling down rather than up. Therefore aim to keep the retrospective on track to discuss the facts and observances and put emphasis that the past is only for concrete experience to draw ideas from. Problem solving activiities should be given more focus than pouring over historical data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
    &lt;strong&gt;Activities Are Better&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve sat in on hundreds of retrospectives, both with activities and without. On the outset, the no-nonsense, just talk about &amp;#8220;what worked, what didn&amp;#8217;t, what to improve&amp;#8221; sounds good, simple, and to the point. However, my experience indicates these were amongst the lowest in terms of effectiveness. For starters I think it keeps people locked into a &amp;#8220;this is a meeting&amp;#8221; mentality and prevents thoughtful activity. Hell, one place I was at just put a word document up with headings titled &amp;#8220;What Worked, What Didn&amp;#8217;t Work, Action Items&amp;#8221; in which Action Items were items the manager would enter into Rally Project Management and assign to people to work on. &lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve found that activities often keep people engaged. In a meeting someone can get by by sitting in front of their laptop staring at the projector, with activities they&amp;#8217;re constantly involved and not given time to disconnect. Additionally, I find the care freeness (or even fun) of activities helps break down some subtle communication barriers and makes people feel more free to speak their minds.
&lt;/li&gt;
&lt;li&gt;
    &lt;strong&gt;Pick Only One Goal&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In theory picking multiple goals sounds great right? We&amp;#8217;ve identified all these impedments and road blocks in our team,process, or environment that really need to be addressed. Why don&amp;#8217;t we just tackle ALL of them rather than ignore them so we can work on removing all of them? This is long the same lines of the theory that maximizing Work-in-Progress maximizes effeciency and we all know that this often fails. LIkewise, by maximizing the number of goals that you have for an iteration you run the risk of context switching too much (not to mention all the focus you&amp;#8217;ll already have towards the work you&amp;#8217;re doing during the iteration) that the team will lose track and quite possibly not make any headway towards any of the goals listed.&lt;/p&gt;
&lt;p&gt;Therefore, limit your Work-in-Progress as a team by selecting one (and only one) goal for the team to work towards during the next iteration. Maybe you&amp;#8217;ll complete it in one day. Maybe you&amp;#8217;ll complete it by the end of the iteration. Maybe you&amp;#8217;ll make progress on it and discover in the next iteration that you uncovered deeper issues that need to be addressed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
    &lt;strong&gt;Follow Up&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One of my biggest mistakes I ever made as a facilitator was failing to help the team follow up on goals&amp;#8230; I assumed you could just let the team form a goal, work out how they would accomplish it, then just let them leave the room with it to schedule into their iteration and complete. Boy was I wrong. Working towards that goal can possibly even grow future retrospective topics, or like I mentioned previously uncover more serious or deeper issues the team needs to address. Failing to follow up can leave the team with a slew of goals they never complete or superficial goals that only kick some dirt over the issue. So it&amp;#8217;s good to recap on the goal that was formed as part of establishing historical data near the beginning of the retrospective and let it help drive new ideas or delve deeper if it wasn&amp;#8217;t completed. Often times you can find incomplete goals correlate to the iteration&amp;#8230; for example if it wasn&amp;#8217;t reached because there wasn&amp;#8217;t enough time to work on it, maybe there&amp;#8217;s not enough slack in the iteration?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Again, out of all these, I&amp;#8217;d have to say the most important is number one: the retrospective belongs to the team. This is an activity for the team by the team to help them inspect and adapt their process and shouldn&amp;#8217;t be something enforced upon them or led by their manager. I ask all ScrumMasters out there to take special care if you facilitate the retrospective&amp;#8230; in my opinion you really shouldn&amp;#8217;t, but if there&amp;#8217;s an absence of facilitation skills you might need to. If this is the case, remember your position&amp;#8230; you are not a manager and therefore should not use this to dictate goals to the team. Stay as neutral as possible and at all costs do not allow yourself to become the owner of a solution, it needs to belong to the team and the team needs to make whatever needs to happen happen. If they need to schedule a task into the iteration, let them do it rather than do it for them. &lt;/p&gt;
&lt;p&gt;Likewise, as a facilitator it is of utmost importance to remain neutral. When I facilitate teams I am on I try to refrain altogether from involvment. Also remember as facilitator it&amp;#8217;s your job to facilitate the discussion, not drive it or offer solutions. I&amp;#8217;ve facilitated a retrospective once where someone called on my expertese with fitnesse to help them solve a recurring fitnesse problem they were having. Sadly, I offered solutions. Looking back, I should have suggested that they come up with a goal, and if they needed help they could come seek me out when I had my developer hat on out on the floor. Further, I often find that when a facilitator from the team participates, they often drive the entire retrospective. Either their ideas lead for the rest to follow (even if they participate last) or the teams participation might fall on deaf ears. I once watched a friend of mine facilitate a retro for our team and draw out a huge value map&amp;#8230; at each time two or three pople would say what they thought the cause was, then he&amp;#8217;d say &amp;#8220;well, I think it&amp;#8217;s really this&amp;#8230;&amp;#8221; and write out his own idea in the map without taking into account what the team said. When I called him out on this he couldn&amp;#8217;t believe he did that. &lt;img src='http://blog.james-carr.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;p&gt;Overall, keep in mind the retrrospective is for finding solutions, not problems. Keep it on track, listen, and help guide the teams to introspect within themselves and find the solutions they need. Most importantly let them do the decision making and above all use the retrospective as their own activity to get better. &lt;img src='http://blog.james-carr.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 28 Feb 2010 10:36:00 CST</pubDate>
      <guid isPermaLink="true">http://blog.james-carr.org/?p=710</guid>
      <dc:creator>James Carr</dc:creator>
    </item>
    <item>
      <title>Scala specs + Mockito == Dead Sexy Examples</title>
      <link>http://www.nofluffjuststuff.com/blog/james_carr/2010/02/scala_specs__mockito__dead_sexy_examples</link>
      <description>&lt;p&gt;Been doing some fooling around with scala for a little bit tonight, and specifically been trying out the BDD framework specs. specs adds some nice stuff to mockito that makes it read like a natural language&amp;#8230; and I like it!&lt;/p&gt;
&lt;p&gt;Take this simple example of stubbing:&lt;/p&gt;
&lt;pre name="code" class="java"&gt;
list.get(0) returns "yo"
&lt;/pre&gt;
&lt;p&gt;Yep&amp;#8230; that&amp;#8217;s perfectly valid scala code&amp;#8230; and totally awesome. &lt;img src='http://blog.james-carr.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;p&gt;Want to verify that a method was invoked with a specific argument?&lt;/p&gt;
&lt;pre name="code" class="java"&gt;
notifier.send(order) was called
&lt;/pre&gt;
&lt;p&gt;And again yes, that is a real line of code pulled from one of my examples. Take a look at more &lt;a href="http://code.google.com/p/specs/wiki/UsingMockito"&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 24 Feb 2010 21:51:00 CST</pubDate>
      <guid isPermaLink="true">http://blog.james-carr.org/?p=708</guid>
      <dc:creator>James Carr</dc:creator>
    </item>
    <item>
      <title>easyb will support behavior tagging</title>
      <link>http://www.nofluffjuststuff.com/blog/andrew_glover/2010/02/easyb_will_support_behavior_tagging</link>
      <description>&lt;p&gt;Back in the Age of Aquarius, I wrote an article entitled &amp;#8220;&lt;A HREF="http://www.ibm.com/developerworks/java/library/j-cq10316/index.html"&gt;Use test categorization for agile builds&lt;/A&gt;&amp;#8221; in which I attempted to delineate various types of tests and then went on to suggest how to categorize these various tests so as to get the most out of a build run (i.e make it fast and effective at providing meaningful feedback).  Back then (and to an extent now) my concern was with test &lt;i&gt;execution&lt;/i&gt;; that is, I like to categorize tests as fast and slow. Accordingly, I run the fast ones all the time, such as before I check-in (I prefer a fast build to be less than 3 minutes &amp;#8212; longer and I get bored). What&amp;#8217;s more, for the slow ones, I usually schedule a build (via Hudson, for instance) that runs them hourly, nightly, etc &amp;#8212; it all depends on how slow they are, man! &lt;/p&gt;
&lt;p&gt;As it turns out, unit-like tests are usually the fast ones and functional-like tests are the slow ones. This all makes sense as functional ones usually &lt;A HREF="http://www.ibm.com/developerworks/java/library/j-cq09266.html"&gt;require a lot of test up&lt;/A&gt;, like seeding a database or firing up Selenium. &lt;/p&gt;
&lt;p&gt;Categorizing tests by execution speed it helpful, but a bit broad in some cases. Thus, I often find myself grouping tests (or behaviors) by feature, behavior or goal. That is, there might be a macro-feature in development broken up by a series of stories (or tests) and I find it&amp;#8217;s helpful to run those stories as a group in isolation for focus. Those behavior groups are then aggregated into iteration builds that correspondingly execute all targeted behaviors, for instance. &lt;/p&gt;
&lt;p&gt;This exercise, combined with the &lt;A HREF="http://www.oracle.com/technology/pub/articles/dev2arch/2006/09/testng-categorization.html"&gt;influence of TestNG&lt;/A&gt; (which supported test groups long long ago) has lead to a new feature in &lt;A HREF="http://easyb.org/"&gt;easyb&lt;/A&gt;: tags. With the &lt;code&gt;tags&lt;/code&gt; keyword, you can categorize a behavior and then  exercise only those desired behaviors via the &lt;code&gt;-tags&lt;/code&gt; command line option or via the &lt;code&gt;tags&lt;/code&gt; attribute in easyb&amp;#8217;s Ant task, for instance.&lt;/p&gt;
&lt;p&gt;Thus, the following story is tagged as &amp;#8220;23949314&amp;#8243; &amp;#8212; this happens to be a &lt;A HREF="http://www.pivotaltracker.com/"&gt;Pivotal Tracker&lt;/A&gt; story ID and in the current iteration, there are 4 stories 23949314, 23949315, 23949316, 23949317. &lt;/p&gt;
&lt;pre class="brush: groovy;"&gt;
tags &amp;quot;23949314&amp;quot;

scenario &amp;quot;AcmeFoo should support expired account deletions&amp;quot;
scenario &amp;quot;AcmeFoo should support child account deletions&amp;quot;
&lt;/pre&gt;
&lt;p&gt;The beauty here is that when this particular story is run, its status is &lt;i&gt;pending&lt;/i&gt;, thus providing some status as to a particular feature. &lt;/p&gt;
&lt;p&gt;Going forward in this iteration, subsequent easyb stories are tagged with appropriate IDs (23949315, etc) and during this iteration, builds are run that exercise these particular tags in isolation. Of course, there are other builds that exercise all other existing stories (via a build pipeline) so as to perform a continuous regression. &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;tags&lt;/code&gt; keyword is flexible too &amp;#8212; you can add multiple tags by including the tag names in a &lt;code&gt;List&lt;/code&gt; like so:&lt;/p&gt;
&lt;pre class="brush: groovy;"&gt;
tags [&amp;quot;23949314&amp;quot;, &amp;quot;functional&amp;quot;]

scenario &amp;quot;AcmeFoo should support expired account deletions&amp;quot;
scenario &amp;quot;AcmeFoo should support child account deletions&amp;quot;
&lt;/pre&gt;
&lt;p&gt;In this case, this story is tagged as both 23949314 &lt;I&gt;and functional&lt;/I&gt; &amp;#8212; accordingly, a build can be configured to  execute only functional behaviors and, of course, this one will be included. Conversely, if a build is run with a tag such as prototype, then this particular story won&amp;#8217;t be executed. &lt;/p&gt;
&lt;p&gt;This is an evolving feature in easyb. Right now, only story level tags are supported. Scenario tagging is planned. What&amp;#8217;s more, tags are currently supported in the tip of &lt;A HREF="http://code.google.com/p/easyb/source/browse"&gt;easyb&amp;#8217;s SVN repository&lt;/A&gt; &amp;#8212; if you&amp;#8217;re eager to start using them now, you&amp;#8217;ll have to &lt;A HREF="http://easyb.org/source.html"&gt;build your own version of easyb&lt;/A&gt;. Otherwise, a release is forthcoming, which will contain this feature. Can you dig it? &lt;/p&gt;
                                 &lt;p&gt;&lt;center&gt;Looking to spin up Continuous Integration &lt;em&gt;quickly&lt;/em&gt;? Check out &lt;a href="http://www.ciinabox.com"&gt;www.ciinabox.com&lt;/a&gt;.&lt;/center&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 22 Feb 2010 18:31:00 CST</pubDate>
      <guid isPermaLink="true">http://thediscoblog.com/?p=1054</guid>
      <dc:creator>Andrew Glover</dc:creator>
    </item>
    <item>
      <title>March of Progress</title>
      <link>http://www.nofluffjuststuff.com/blog/howard_lewis_ship/2010/02/march_of_progress</link>
      <description>&lt;p&gt;Or should that be "Late February of Progress".  I have to say I'm a bit envious right now of Rich Hickey ... I can see that he's continuing on like a steam roller, extending and improving Clojure.  I guess he's having some success in generating &lt;a href="http://clojure.org/funders"&gt;Research and Design budget from funding companies&lt;/a&gt;.  I can see, following his threads, that he's working on yet more concurrency metaphors for Clojure, which is a good thing (though eventually there'll need to be a big book just to describe them all).

&lt;p&gt;
I'm on a different track, in that I fund Tapestry out of pocket while doing training and project work. In some cases, those merge, such as when I add specific features to Tapestry for a specific client.

&lt;p&gt;
I'm of two minds here: doing project work keeps me grounded in real requirements for Tapestry. I see what works really well, and what needs some polishing. On the other hand, I come up with ideas for new components, improvements, and integrations &lt;em&gt;all the time&lt;/em&gt; and barely have enough free time (between clients, ordinary Tapestry maintenance, and &lt;a href="http://www.flickr.com/photos/hlship/4360845779/in/set-72157623319565355/"&gt;this special project&lt;/a&gt;) to even document my ideas, never mind implement, test and distribute them.

&lt;p&gt;
So, should I set up a funding option like Rich's?  Well, that wouldn't help my current clients (I'm committed to getting their apps into production), but it may change how I would look for future work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-5549483775211075380?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/DhWLuqQur7A" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 22 Feb 2010 12:15:20 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-5549483775211075380</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Setting up Clojure 1.1.0 on Mac OSX</title>
      <link>http://www.nofluffjuststuff.com/blog/ken_sipe/2010/02/setting_up_clojure_1_1_0_on_mac_osx</link>
      <description>As part of the &lt;a href="http://lambdalounge.org/"&gt;Lambda Lounge&lt;/a&gt;, established by Alex Miller (Thanks!!), we have started a group to study the SICP.    We just started and are going virtual... if you would like to participate, email or tweet me (@kensipe).   In the process of studying SICP and LISP, I plan on focusing on Clojure.  Clojure was previously on my machine as I was reading Stu's book &lt;a href="http://www.amazon.com/Programming-Clojure-Pragmatic-Programmers-Halloway/dp/1934356336"&gt;Programming Clojure&lt;/a&gt;, however increased usage would require some maturing of my tools.  This led to the discovery of Mark Reid's blog on &lt;a href="http://mark.reid.name/sap/setting-up-clojure.html"&gt;Setting up Clojure for Mac OS X&lt;/a&gt;, however I assume based on updates and changes over the last year, it requires some updates.&lt;br /&gt;&lt;br /&gt;Read Mark's blog first... getting clojure, the clojure-contrib and jline.  Here are the differences:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create an environment variable CLOJURE_HOME assigned to the directory for clojure&lt;/li&gt;&lt;li&gt;Create the /bin directory for the clj script included below&lt;/li&gt;&lt;li&gt;Add $CLOJURE_HOME/bin in the $PATH&lt;/li&gt;&lt;li&gt;Clojure is distributed with clojure.jar in the CLOJURE_HOME... so I maintain that.  It is expected that contrib and jline are in the same directory.&lt;/li&gt;&lt;li&gt;Mark's clj script has been updated below... The previous script invokes classes which are depreciated.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Here is the updated script:&lt;br /&gt;&lt;pre class="brush: bash"&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;# Runs Clojure using the classpath specified in the `.clojure` file of the&lt;br /&gt;# current directory.&lt;br /&gt;#&lt;br /&gt;# Ken Sipe &lt;http: com=""&gt;  2010-02-20&lt;br /&gt;# Inspired by Mark Reid &lt;http: name=""&gt;&lt;br /&gt;# original: http://github.com/mreid/clojure-framework/blob/e1c80cc650f448713243be8272dba1fa3c1a7cea/clj&lt;br /&gt;#&lt;br /&gt;# This scripts expects $JAVA_HOME and $CLOJURE_HOME to be defined for the system it is running on&lt;br /&gt;# The clojure.jar is standardly in the clojure_home dir (and not in the lib directory), so&lt;br /&gt;# the expectation is that clojure-contrib.jar and the jline.jar are placed in the same dir&lt;br /&gt;&lt;br /&gt;CLJ_DIR=$CLOJURE_HOME&lt;br /&gt;CLOJURE=$CLJ_DIR/clojure.jar&lt;br /&gt;CONTRIB=$CLJ_DIR/clojure-contrib.jar&lt;br /&gt;JLINE=$CLJ_DIR/jline-0_9_5.jar&lt;br /&gt;CP=$PWD:$CLOJURE:$JLINE:$CONTRIB&lt;br /&gt;&lt;br /&gt;# Add extra jars as specified by `.clojure` file&lt;br /&gt;if [ -f .clojure ]&lt;br /&gt;then&lt;br /&gt;   CP=$CP:`cat .clojure`&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ -z "$1" ]; then&lt;br /&gt;   java -server -cp $CP \&lt;br /&gt;        jline.ConsoleRunner clojure.lang.Repl&lt;br /&gt;else&lt;br /&gt;   java -server -cp $CP clojure.main -i $*&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;Love the TextMate support and the history support in JLine!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7461275049781191261-6961516311112589806?l=kensipe.blogspot.com' alt='' /&gt;&lt;/div&gt;</description>
      <pubDate>Sun, 21 Feb 2010 22:27:00 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-7461275049781191261.post-6961516311112589806</guid>
      <dc:creator>Ken Sipe</dc:creator>
    </item>
    <item>
      <title>The Power of the Backchannel</title>
      <link>http://www.nofluffjuststuff.com/blog/nathaniel_schutta/2010/02/the_power_of_the_backchannel</link>
      <description>&lt;p&gt;Last week, I spoke at the &lt;a href="http://www.nejug.org/events/show/107"&gt;New England Java Users Group&lt;/a&gt;, one of the biggest and best around. I had a rocking good time, the audience was outstanding and &lt;a href="http://dave-klein.blogspot.com/"&gt;Dave Klein&lt;/a&gt; (author of the outstanding &lt;a href="http://www.amazon.com/gp/product/1934356468?ie=UTF8&amp;#038;tag=ntschuttacom-20&amp;#038;linkCode=as2&amp;#038;camp=1789&amp;#038;creative=390957&amp;#038;creativeASIN=1934356468"&gt;Grails: A Quick-Start Guide&lt;/a&gt;) was even there! Anyway, one of the attendees, Deborah Hamill (VP Engineering at &lt;a href="http://www.accordare.com"&gt;Accordare&lt;/a&gt;, Inc.), was kind enough to collect up all the links I referenced during the talk &amp;#8211; &lt;em&gt;including ones that weren&amp;#8217;t even on my slides&lt;/em&gt;! Many thanks Deborah, I appreciate it. By the way, said slides can be found &lt;a href="http://ntschutta.com/jat/conference-slides/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ntschutta.com/jat/"&gt;http://ntschutta.com/jat/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blog.objectmentor.com/articles/2009/02/26/10-papers-every-programmer-should-read-at-least-twice"&gt;http://blog.objectmentor.com/articles/2009/02/26/10-papers-every-programmer-should-read-at-least-twice&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://jania.pe.kr/aw/moin.cgi/JSSpec"&gt;http://jania.pe.kr/aw/moin.cgi/JSSpec&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.jsunit.net/"&gt;http://www.jsunit.net/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.extjs.com/"&gt;http://www.extjs.com/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Ext_(JavaScript_library)"&gt;http://en.wikipedia.org/wiki/Ext_(JavaScript_library)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://developer.yahoo.com/yslow/"&gt;http://developer.yahoo.com/yslow/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blog.inspired.no/google-releases-page-speed-for-firebug-665"&gt;http://blog.inspired.no/google-releases-page-speed-for-firebug-665&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.prototypejs.org/"&gt;http://www.prototypejs.org/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.crockford.com/"&gt;http://www.crockford.com/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://developer.yahoo.com/yui/"&gt;http://developer.yahoo.com/yui/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://github.com/"&gt;http://github.com/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.jslint.com/"&gt;http://www.jslint.com/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://code.google.com/closure/"&gt;http://code.google.com/closure/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.paulgraham.com/pypar.html"&gt;http://www.paulgraham.com/pypar.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html"&gt;http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.javascripter.net/faq/reserved.htm"&gt;http://www.javascripter.net/faq/reserved.htm&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.joehewitt.com/"&gt;http://www.joehewitt.com/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.thefrontside.net/"&gt;http://www.thefrontside.net/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Acronyms&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Domain-specific_language"&gt;http://en.wikipedia.org/wiki/Domain-specific_language&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development"&gt;http://en.wikipedia.org/wiki/Behavior_Driven_Development&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Continuous_integration"&gt;http://en.wikipedia.org/wiki/Continuous_integration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Others Deborah found while searching for my topics:&lt;br /&gt;
&lt;a href="http://blog.inspired.no/javascript-error-logging-with-ajax-154"&gt;http://blog.inspired.no/javascript-error-logging-with-ajax-154&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://writecodeonline.com/javascript/"&gt;http://writecodeonline.com/javascript/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.infoq.com/articles/javascript-tdd"&gt;http://www.infoq.com/articles/javascript-tdd&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 21 Feb 2010 16:08:00 CST</pubDate>
      <guid isPermaLink="true">http://ntschutta.com/jat/?p=477</guid>
      <dc:creator>Nathaniel Schutta</dc:creator>
    </item>
    <item>
      <title>DynamicDomainProperties and the AGPL</title>
      <link>http://www.nofluffjuststuff.com/blog/robert_fischer/2010/02/dynamicdomainproperties_and_the_agpl</link>
      <description>&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.fsf.org/licensing/licenses/agpl-3.0.html"&gt;&lt;img src="http://www.gnu.org/graphics/agplv3-155x51.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_blank" href='http://www.pledgie.com/campaigns/9065'&gt;&lt;img alt='Click here to lend your support to: Un-AGPL DynamicDomainProperties 1.0 and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/9065.png?skin_name=chrome' border='0'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I just released the DynamicDomainProperties plugin for Grails, which allows domain classes to have dynamic properties. It&amp;#8217;s pretty nifty, if I do say so myself.&lt;/p&gt;
&lt;p&gt;Based on &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/open-letter-to-burt-beckwith/"&gt;my frustration with the Grails plugin culture&lt;/a&gt; because of &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/open-source-users/"&gt;differing cultural assumptions about open source works&lt;/a&gt;, and based on &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/self-destructive-oss/"&gt;my lack of appreciation for the promises of indirect compensation offered to me as an open source developer&lt;/a&gt;, I&amp;#8217;ve decided to release it under the &lt;a rel="nofollow" target="_blank" href="http://www.fsf.org/licensing/licenses/agpl-3.0.html"&gt;GNU-Affero GPL 3.0&lt;/a&gt;, which is like the GPL but (among other things) requires the source to be available to the users of a web app that use this plugin.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m open to the idea of releasing it under the more &amp;#8220;biz-friendly&amp;#8221; BSD, but then &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/a-defense-of-the-gpl/"&gt;I&amp;#8217;m going to want a different form of compensation&lt;/a&gt;. So I&amp;#8217;m putting up a bounty via Pledgie: if I was building this plugin as a consultant, it would have cost a client about $2500. So, if the commercial community contributes $2500, I&amp;#8217;ll do a BSD release. Anyone who donates $250 or more gets a single-domain usage license right away.&lt;/p&gt;
&lt;p&gt;For more information on the plugin, see &lt;a rel="nofollow" target="_blank" href="http://grails.org/plugin/dynamic-domain-properties"&gt;the plugin page on grails.org&lt;/a&gt;. (I&amp;#8217;ve had enough difficulty with GitHub&amp;#8217;s wiki freaking out on me and would rather avoid that.)&lt;/p&gt;
&lt;hr /&gt;&lt;h2&gt;Comments&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/#comment-37286"&gt;February 22, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.anyware.co.uk' class='url'&gt;Marc Palmer&lt;/a&gt; wrote: I'm interested to see how this pans out Robert - good luck!&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/#comment-37328"&gt;March 4, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://gr8fanboy.wordpress.com/' class='url'&gt;Jeremy Flowers&lt;/a&gt; wrote: Way to go. This looks like the way forward to me. In the Microsoft' arena GUI component vendors started to sell there wares this way too, like Infragistics. I always thought plug-ins would have to go the same way to get support for your plug-ins. You have to put food on the table somehow..&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/#comment-37338"&gt;March 5, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://metasieve.wordpress.com/2010/03/05/does-grails-have-a-problem/' class='url'&gt;Does Grails have a problem? &amp;laquo; The MetaSieve Blog&lt;/a&gt; wrote: [...] I have time to, I can completely comprehend Robert&amp;#8217;s point of view and his desire to get a different kind of compensation for his open source work. In fact, there should be plenty of space for both approaches (and [...]&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/#comment-37447"&gt;March 18, 2010&lt;/a&gt;, Sakuraba wrote: What part of those profits will go back to the creators of the software you benefit from? What if you had to pay for using Grails source code? You basically take freedom, but you close down your extensions on top of that. How is that fair? In my mind, if you dont stand by your contributions and pass by the freedoms that you have received to others, you shouldnt release those contributions at all.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/#comment-37448"&gt;March 18, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://enfranchisedmind.com/blog/posts/author/candide/' class='url'&gt;Robert Fischer&lt;/a&gt; wrote: The Grails source code developers aren't asking for AGPL freedom. They're apparently feeling sufficiently compensated with the Grails Apache license: indeed, they've done very well by it. And they've done very well by touting the number of (totally uncompensated) open source plugins which are available for the platform they built. My plugin makes their platform more valuable by its very existence. So they're certainly getting their compensation. I, on the other hand, am not sufficiently compensated by the Apache license, so I'm releasing it under the free-as-in-freedom AGPL as my compensation. Even more, I'm not "closing down" my extension, but actually asking for exactly the kind of freedom-in-kind that you're describing. You can use my plugin all you'd like: your web-app just has to be free-as-in-freedom, too. If Grails wanted that kind of license, they could have released under the AGPL.&lt;/li&gt;&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/#comment-37449"&gt;March 18, 2010&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href='http://www.google.com/profiles/raphaelmiranda' class='url'&gt;Raphael Miranda&lt;/a&gt; wrote: I find awesome your endeavor. We all love open-source but monetizing from it is often really hard if you're not Jboss, Sun or Mozilla. I've made a donation. Not for this plugin especificaly but for this and all others that you have contributed and that make my job easier. Thanks Rob.&lt;/li&gt;&lt;/ul&gt;&lt;hr /&gt;
This post was by &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/author/candide/"&gt;Robert Fischer&lt;/a&gt;, written on February 20, 2010.&lt;br /&gt;
Comment on this post: &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/#respond"&gt;http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/#respond&lt;/a&gt;&lt;br /&gt;
Public Permalink: &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/"&gt;http://enfranchisedmind.com/blog/posts/dynamicdomainproperties-grails-plugin-agpl/&lt;/a&gt;
&lt;hr /&gt;&lt;a rel="nofollow" target="_blank" href="http://creativecommons.org/licenses/by-sa/3.0/us/"&gt;&lt;img alt="Creative Commons License" style="border-width:0;" src="http://i.creativecommons.org/l/by-sa/3.0/us/88x31.png"/&gt;&lt;/a&gt;&lt;br /&gt;This article was a post on &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog"&gt;the EnfranchisedMind blog&lt;/a&gt;. &lt;span&gt;EnfranchisedMind Blog&lt;/span&gt; by &lt;a rel="nofollow" target="_blank" href="http://enfranchisedmind.com/blog/"&gt;Robert Fischer, Brian Hurt, and Other Authors&lt;/a&gt; is licensed under a &lt;a rel="nofollow" target="_blank" href="http://creativecommons.org/licenses/by-sa/3.0/us/"&gt;Creative Commons Attribution-Share Alike 3.0 United States License&lt;/a&gt;.&lt;p style="display:none;"&gt;(Digital Fingerprint: bcecb67d74ab248f06f068724220e340 (68.142.243.103) )&lt;/p&gt;</description>
      <pubDate>Sat, 20 Feb 2010 18:24:00 CST</pubDate>
      <guid isPermaLink="true">http://enfranchisedmind.com/blog/?p=2309</guid>
      <dc:creator>Robert Fischer</dc:creator>
    </item>
    <item>
      <title>links for 2010-02-20</title>
      <link>http://www.nofluffjuststuff.com/blog/james_carr/2010/02/links_for_2010_02_20</link>
      <description>&lt;ul class="delicious"&gt;
&lt;li&gt;
&lt;div class="delicious-link"&gt;&lt;a href="http://www.slideshare.net/vivek_prahlad/functional-testing-swing-applications-with-frankenstein"&gt;Functional Testing Swing Applications with Frankenstein&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Sat, 20 Feb 2010 07:01:00 CST</pubDate>
      <guid isPermaLink="true">http://blog.james-carr.org/2010/02/20/links-for-2010-02-20/</guid>
      <dc:creator>James Carr</dc:creator>
    </item>
    <item>
      <title>Evolving the Meta Programming in Tapestry 5</title>
      <link>http://www.nofluffjuststuff.com/blog/howard_lewis_ship/2010/02/evolving_the_meta_programming_in_tapestry_5</link>
      <description>&lt;p&gt;I've set a goal of &lt;a href="http://tapestryjava.blogspot.com/2010/01/tapestry-and-bytecode-generation.html"&gt;removing Javassist&lt;/a&gt; from Tapestry 5 and I've made some nice advances on that front. Tapestry uses Javassist inside the web framework layer to load and transform component classes.

&lt;p&gt;
All that code is now rewritten to updated APIs that no longer directly expose Javassist technology. In other words, where in the past, the transformer code would write psuedo-Java and add it to a method using Javassist (for example adding &lt;code&gt;value = null;&lt;/code&gt; to the &lt;code&gt;containingPageDidDetach()&lt;/code&gt; method), Tapestry 5.2 will instead add advice to the (otherwise empty) &lt;code&gt;containingPageDidDetach()&lt;/code&gt; method, and the advice will use a &lt;code&gt;FieldAccess&lt;/code&gt; object to set the &lt;code&gt;value&lt;/code&gt; field to null.

&lt;p&gt;
Basically, I've vastly reduced the number of operations possible using the ClassTransformation API. Before, it was pretty much unbounded due to the expressive power of Javassist. Now a small set of operations exist that can be combined into any number of desired behaviors:

&lt;ul&gt;
&lt;li&gt;Add new implemented interfaces to a component Class
&lt;li&gt;Add new fields to a Class
&lt;li&gt;Initialize the value of a field to a fixed value, or via a per-instance callback
&lt;li&gt;Delegate read and write access to a field to a provided FieldValueConduit delegate
&lt;li&gt;Add new methods to a component Class with empty implementations
&lt;li&gt;Add advice to any method of a class
&lt;li&gt;Create a MethodAccess object from a method, to allow a method to be invoked (regardless of visibility)
&lt;li&gt;Create a FieldAccess object from a field, to allow the field to be read or updated (regardless of visibility)
&lt;/ul&gt;

&lt;p&gt;What's amazing is that these few operations, combined in different ways, supports all the different meta-programming possible in Tapestry 5.1. There's costs and benefits to this new approach.

&lt;h4&gt;Costs&lt;/h4&gt;

&lt;p&gt;There will be many more objects associated with each component class: new objects to represent advice on methods, and new objects to provide access to private component fields and methods.
&lt;p&gt;Javassist could be brutally efficient, the new approach adds several layers of method invocation that was not present in 5.1.
&lt;p&gt;Incorrect use of method advice can corrupt or disable logic provided by the framework and is hard to debug.

&lt;h4&gt;Benefits&lt;/h4&gt;

&lt;p&gt;We can eventually switch out Javassist for a more stable, more mainstream, better supported framework such as ASM. ASM should have superior performance to Javassist (no tedious Java-ish parse and compile, just raw bytecode manipulation).
&lt;p&gt;The amount of generated bytecode is lower is many cases. Fewer methods and fields to accomplish the same behavior.
&lt;p&gt;The generated bytecode is more regular across different utilizations: fewer edge cases, less untested, generated bytecode
&lt;p&gt;Key logic returns to "normal" code space, rather than being indirectly generated into "Javassist" code space ... this is easier to debug as there's some place to put your breakpoints!

&lt;h4&gt;Summary&lt;/h4&gt;

&lt;p&gt;Overall, I'm pretty happy with what's been put together so far. In the long run, we'll trade instantiation of long lived objects for dynamic bytecode generation. There's much more room to create ways to optimize memory utilization and overall resource utilization and the coding model is similar (closures and callbacks vs. indirect programming via Javassist script). I'm liking it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-7987949792492560735?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/I7xCI6fJkBE" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 19 Feb 2010 19:57:16 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-7987949792492560735</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Git SVN On Windows</title>
      <link>http://www.nofluffjuststuff.com/blog/james_carr/2010/02/git_svn_on_windows</link>
      <description>&lt;p&gt;At work we use svn and lately I&amp;#8217;ve been trying &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-svn.html"&gt;git svn&lt;/a&gt; to maintain a local git repository that I can push to the svn server. So far, I love it! The best feature is being able to use &lt;code&gt;&lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-stash.html"&gt;git stash&lt;/a&gt;&lt;/code&gt; to &amp;#8220;stash away&amp;#8221; the current dirty workspace, work on something (say a defect), commit and then call &lt;code&gt;git stash pop&lt;/code&gt; to return to what I was working on.&lt;/p&gt;
&lt;p&gt;Setup is quite easy&amp;#8230; on windows, you need to install &lt;a href="http://www.cygwin.com/"&gt;Cygwin&lt;/a&gt; and under &lt;strong&gt;devel&lt;/strong&gt; package select &lt;strong&gt;git&lt;/strong&gt; and &lt;strong&gt;git-svn&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Once it&amp;#8217;s installed, just follow the following steps to get started:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;git svn init http://path/to/svn/project/trunk projectname&lt;/li&gt;
&lt;li&gt;cd projectname&lt;/li&gt;
&lt;li&gt;git svn fetch -rREVISION (most likely this will be git svn fetch -rHEAD&lt;/li&gt;
&lt;li&gt;git svn rebase&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;#8217;s it&amp;#8230; all the usual git commands will work, and when you&amp;#8217;re ready to commit just type &lt;strong&gt;git svn dcommit&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My only worry is that I have yet to have a conflict, and I&amp;#8217;m afraid I&amp;#8217;ll be hosed without my usual eclipse conflict compare. &lt;img src='http://blog.james-carr.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; &lt;/p&gt;</description>
      <pubDate>Fri, 19 Feb 2010 09:18:00 CST</pubDate>
      <guid isPermaLink="true">http://blog.james-carr.org/?p=703</guid>
      <dc:creator>James Carr</dc:creator>
    </item>
    <item>
      <title>Book Review: DSLs in Boo</title>
      <link>http://www.nofluffjuststuff.com/blog/andrew_glover/2010/02/book_review_dsls_in_boo</link>
      <description>&lt;div style="float:right; padding-left:1.0em; padding-top:0.0em;"&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=thdibl-20&amp;#038;o=1&amp;#038;p=8&amp;#038;l=as1&amp;#038;asins=1933988606&amp;#038;fc1=000000&amp;#038;IS2=1&amp;#038;lt1=_blank&amp;#038;m=amazon&amp;#038;lc1=0000FF&amp;#038;bc1=000000&amp;#038;bg1=FFFFFF&amp;#038;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;While I don&amp;#8217;t spend a lot of time on the .NET platform anymore, I&amp;#8217;m still &lt;A HREF="http://www.infoq.com/articles/boo-intro"&gt;a big fan of Boo&lt;/A&gt;. Having cut &lt;A HREF="http://www.oreillynet.com/pub/a/python/2005/01/13/cheetah.html"&gt;my teeth on Python&lt;/A&gt; many years ago, I&amp;#8217;ve always enjoyed hip &lt;A HREF="http://thediscoblog.com/category/languages/python/"&gt;Pythonic languages&lt;/A&gt; and when Boo came out for the .NET platform way back when, I jumped on the opportunity to experiment with it and leverage it at client sites. What&amp;#8217;s more, it&amp;#8217;s no secret that &lt;A HREF="http://easyb.org"&gt;I&amp;#8217;m a fan of DSLs&lt;/A&gt; as I do find they can be quite powerful, for example, in leveraging natural language semantics that enhance the &amp;#8220;user experience&amp;#8221; such as with expressing &lt;I&gt;&lt;A HREF="http://thediscoblog.com/2010/02/02/introduction-to-easyb-video/"&gt;intent&lt;/A&gt;&lt;/I&gt;.&lt;/p&gt;
&lt;p&gt;Thus, when I had a chance to read &lt;A HREF="http://ayende.com/blog/default.aspx"&gt;Ayende Rahien&lt;/A&gt;&amp;#8217;s &amp;#8220;&lt;a href="http://www.amazon.com/gp/product/1933988606?ie=UTF8&amp;#038;tag=thdibl-20&amp;#038;linkCode=as2&amp;#038;camp=1789&amp;#038;creative=9325&amp;#038;creativeASIN=1933988606"&gt;DSLs in Boo&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=thdibl-20&amp;#038;l=as2&amp;#038;o=1&amp;#038;a=1933988606" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&amp;#8220;, I jumped at the opportunity, baby! Ayende does a great job of of introducing the notion of DSLs (interestingly, there isn&amp;#8217;t a ton of literature here specifically about DSLs alone other than &lt;A HREF="http://martinfowler.com/bliki/DomainSpecificLanguage.html"&gt;Martin Fowler&lt;/A&gt;&amp;#8217;s bliki and of course, &lt;A HREF="http://en.wikipedia.org/wiki/Domain-specific_language"&gt;Wikipedia&lt;/A&gt;) in the first chapter, specifically covering the various types of DSLs (i.e. internal, external, and he goes on to define graphical ones plus he reluctantly includes fluent interfaces). What&amp;#8217;s more, he also explores why one would want to write an DSL. Here he covers a few reasons, but a quote stuck out regarding one particular reason, which is for expressing&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;rules and actions in a way that&amp;#8217;s close to the domain and understandable to business people&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This is, of course, the intent of easyb &amp;#8212; that is, to express intentions in an easily understandable language that stakeholders can grasp. &lt;/p&gt;
&lt;p&gt;After chapter 1, Ayende goes on to cover the &lt;A HREF="http://boo.codehaus.org/"&gt;basics of Boo&lt;/A&gt;, which, of course, would be needed should you want to actually create a DSL in Boo! It isn&amp;#8217;t until chapter 4, however, that you start to get your hands dirty coding DSLs; nevertheless, I understand the need to introduce the various required concepts leading up to chapter 4. Thus, in chapter 4, a few high level examples are covered. &lt;/p&gt;
&lt;p&gt;Later chapters go into some details about writing and maintaining DSL code; plus, in chapter 7, he unveils Rhino DSL, which is an open source project that facilitates authoring DSLs in Boo (Ayende, by the way, is a prolific coder &amp;#8212; he&amp;#8217;s all over the map in the .NET world). Chapter 8 finally covers testing a DSL, which I can attest as quite difficult but paramount to a DSL&amp;#8217;s success and stability. He also goes on to cover versioning, which I found quite intriguing as backward compatibility is a double-edged sword. &lt;/p&gt;
&lt;p&gt;What I find most interesting is the way in which a base language affects the resulting implementation of a DSL (i.e. the end result). That is, Pythonic DSLs still have the oft complained about &amp;#8220;&lt;A HREF="http://weblog.hotales.org/cgi-bin/weblog/nb.cgi/view/python/2005/02/19/1"&gt;white-space issue&lt;/A&gt;.&amp;#8221; For instance, here is a code snippet from the book for an order processing engine:&lt;/p&gt;
&lt;pre class="brush: python;"&gt;
upon auth_denied:
  when preferred_customer:
       delay_order_until_payment_is_authorized &amp;quot;preferred customer benefit&amp;quot;
  when default_customer:
       cancel_order &amp;quot;no money, no order&amp;quot;
&lt;/pre&gt;
&lt;p&gt;Note how the underlying language (Boo) forces the DSL to use spaces (rather than say brackets or &lt;code&gt;def&lt;/code&gt;/&lt;code&gt;do&lt;/code&gt;/&lt;code&gt;end&lt;/code&gt; like calls), what&amp;#8217;s more, underscores (i.e. _) are required so as to keep the compiler happy. It&amp;#8217;s, in many ways, the same in something like &lt;a href="http://code.google.com/p/easyb/"&gt;easyb&lt;/a&gt; (which is, of course, backed by &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;), which is essentially forced to use brackets and in one case, a comma like so:&lt;/p&gt;
&lt;pre class="brush: groovy;"&gt;
given &amp;quot;a preferred customer&amp;quot;, {
  //blah blah
}
&lt;/pre&gt;
&lt;p&gt;Note how Groovy requires the DSL to include a comma between the description &lt;code&gt;String&lt;/code&gt; and the &lt;code&gt;Closure&lt;/code&gt;. Ruby, by the way, and in the case of something like &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;, doesn&amp;#8217;t have this requirement. For instance, in &lt;A HREF="http://thediscoblog.com/2007/08/28/is-bdd-tdd-done-right/"&gt;RSpec&lt;/A&gt;:&lt;/p&gt;
&lt;pre class="brush: ruby;"&gt;
it &amp;quot;should return item enqueued&amp;quot; do
  @queue.enqueue(&amp;quot;test&amp;quot;)
  @queue.dequeue.should == &amp;quot;test&amp;quot;
end
&lt;/pre&gt;
&lt;p&gt;Yet, notice the &lt;code&gt;do&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt;! Needless to say, you can see similar influences in something like &lt;A HREF="http://thediscoblog.com/2009/11/16/comparing-scala-and-groovy-via-scalatest-and-easyb/"&gt;Scala&lt;/A&gt; too. &lt;/p&gt;
&lt;p&gt;DSLs are interesting beasts and they&amp;#8217;ve clearly affected productivity on various platforms (need I remind you that &lt;A HREF="http://en.wikipedia.org/wiki/Ruby_on_Rails"&gt;Rails&lt;/A&gt; is a DSL?). &amp;#8220;&lt;a href="http://www.amazon.com/gp/product/1933988606?ie=UTF8&amp;#038;tag=thdibl-20&amp;#038;linkCode=as2&amp;#038;camp=1789&amp;#038;creative=9325&amp;#038;creativeASIN=1933988606"&gt;DSLs in Boo&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=thdibl-20&amp;#038;l=as2&amp;#038;o=1&amp;#038;a=1933988606" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&amp;#8221; specifically explores DSLs on a specific platform, yet it&amp;#8217;s still an interesting read. Because it&amp;#8217;s my bag, I&amp;#8217;m definitely looking forward to more books exploring DSLs as a main subject! All in all though, this is an interesting book &lt;em&gt;regardless of your chosen platform&lt;/em&gt;. Can you dig it, man?&lt;/p&gt;
                                 &lt;p&gt;&lt;center&gt;Looking to spin up Continuous Integration &lt;em&gt;quickly&lt;/em&gt;? Check out &lt;a href="http://www.ciinabox.com"&gt;www.ciinabox.com&lt;/a&gt;.&lt;/center&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 18 Feb 2010 17:34:00 CST</pubDate>
      <guid isPermaLink="true">http://thediscoblog.com/?p=1022</guid>
      <dc:creator>Andrew Glover</dc:creator>
    </item>
  </channel>
</rss>

