<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7206939994948735545</id><updated>2012-02-16T13:52:23.397+02:00</updated><category term='ruby'/><category term='feeds'/><category term='mocks'/><category term='reflection'/><category term='javascript'/><category term='clojure'/><category term='burnout'/><category term='actors'/><category term='option'/><category term='graphs'/><category term='xterm'/><category term='muCommander'/><category term='anxiety'/><category term='portable'/><category term='python'/><category term='BeanShell'/><category term='productivity'/><category term='closures'/><category term='greasemonkey'/><category term='structural types'/><category term='interpolation'/><category term='linux'/><category term='screen'/><category term='id3v2'/><category term='extensions'/><category term='scala'/><category term='id3'/><category term='stress'/><category term='channel'/><category term='time boxing'/><category term='partialfunction'/><category term='OpenOffice'/><category term='ssh'/><category term='XML'/><category term='Java'/><category term='bash'/><category term='lift'/><category term='extractors'/><category term='null'/><category term='pattern matching'/><category term='interpreter'/><category term='Firefox'/><category term='desktop'/><category term='groovy'/><category term='slitaz'/><category term='testframework'/><category term='twitter'/><category term='languages'/><category term='multiple assignment'/><category term='akka'/><category term='mp3'/><category term='fantom'/><category term='ubuntu'/><category term='testing'/><category term='command_not_found'/><category term='pomodoro'/><category term='implicit conversions'/><title type='text'>Speaking my (programming) language?</title><subtitle type='html'>Technical notes about programming hacks I found useful. Dabbling in scripting languages, Linux utilities, Java and programmer productivity.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-1810350731474102891</id><published>2011-07-31T07:54:00.001+03:00</published><updated>2011-07-31T07:56:45.019+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='partialfunction'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Partially unexpected effects of chaining partial functions in Scala</title><content type='html'>&lt;p&gt;People who learn Scala usually agree that pattern matching is a great feature which helps make your code more expressive. Some time later they also discover that partial functions used in the match statement can also be used separately. And since partial functions are full-blown functions, you can &lt;a class="reference external" href="http://daily-scala.blogspot.com/2010/02/chaining-partial-functions-with-orelse.html"&gt;combine them&lt;/a&gt; in a couple useful ways:&lt;/p&gt;&lt;br /&gt;&lt;dl class="docutils"&gt;&lt;br /&gt;&lt;dt&gt;f1 orElse f2&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Combines two partial function in a new one; if f1 is not defined in its argument, tries f2.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;f1 andThen f2&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Applies the result of f1 to f2. This means that the output of f1 must be a type compatible with the input of f2&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;&lt;div class="section" id="orelse"&gt;&lt;br /&gt;&lt;h4&gt;orElse&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;As others have &lt;a class="reference external" href="http://scalaeveryday.com/?p=67"&gt;discovered&lt;/a&gt;, you can combine a list (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;TraversableOnce&lt;/span&gt;&lt;/tt&gt; really) of partial functions into one with reduce. What's not so obvious though is that the way you combine them can lead to unexpected perfomance consequences.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In order to easily create a lot of partial functions to test, we will create a higher-order function to generate them (if you're used to Java, you can call it a factory). The produced partial function will print a short message when its &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isDefinedAt&lt;/span&gt;&lt;/tt&gt; method is called (not when it's applied):&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;genPF&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;defined&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;defined&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="n"&gt;defined&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;f123&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;genPF&lt;/span&gt; &lt;span class="n"&gt;reduceLeft&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="n"&gt;orElse&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Let's try it:&lt;/p&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;&amp;gt; f123(1)&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;1&lt;br /&gt;&amp;gt; f123(2)&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;&amp;gt; f123(3)&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Wait, what? The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isDefinedAt&lt;/span&gt;&lt;/tt&gt; method is called up to 6 times. It gets even worse with a bigger number of composed functions.&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;f1to5&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;genPF&lt;/span&gt; &lt;span class="n"&gt;reduceLeft&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="n"&gt;orElse&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;&amp;gt; f1to5(2)&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;&amp;gt; f1to5(3)&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;&amp;gt; f1to5(4)&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Let's take a closer look at the definition of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isDefinedAt&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;apply&lt;/span&gt;&lt;/tt&gt; of the function created with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;orElse&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A1&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;:&lt;/span&gt; &lt;span class="kt"&gt;A&lt;/span&gt;, &lt;span class="kt"&gt;B1&lt;/span&gt; &lt;span class="k"&gt;&amp;gt;:&lt;/span&gt; &lt;span class="kt"&gt;B&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PartialFunction&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A1&lt;/span&gt;, &lt;span class="kt"&gt;B1&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt; &lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PartialFunction&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A1&lt;/span&gt;, &lt;span class="kt"&gt;B1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt;&lt;br /&gt;  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PartialFunction&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;A1&lt;/span&gt;, &lt;span class="kt"&gt;B1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;isDefinedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;A1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;br /&gt;    &lt;span class="nc"&gt;PartialFunction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isDefinedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isDefinedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;A1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;B1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PartialFunction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isDefinedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="nc"&gt;PartialFunction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;When you apply a composed partial function, we first check if it's defined in either f1 or f2, and then we check f1 again, so that we know &lt;em&gt;which one&lt;/em&gt; to call. This means that in the worst case, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isDefinedAt&lt;/span&gt;&lt;/tt&gt; for f1 is called twice.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Given this, we can explain what happens here. The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isDefinedAt&lt;/span&gt;&lt;/tt&gt; delegates to the composed functions' methods, and when it's called twice... you know what happens when we do this again and again. We can fairly easily find out that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isDefinedAt&lt;/span&gt;&lt;/tt&gt; is called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;k&lt;/span&gt; &lt;span class="pre"&gt;*&lt;/span&gt; &lt;span class="pre"&gt;(n&lt;/span&gt; &lt;span class="pre"&gt;-&lt;/span&gt; &lt;span class="pre"&gt;k&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;1)&lt;/span&gt;&lt;/tt&gt; times, where n: number of composed functions, k: the first function that matches.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Luckily, there is an easy solution to combine partial functions in a more efficient way. We can use reduceRight, where &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;isDefinedAt&lt;/span&gt;&lt;/tt&gt; for each composed function is invoked at most twice. Verifying this and finding out why is left as an exercise for the curious reader (as you undoubtedly are, since you're reading this).&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section" id="andthen"&gt;&lt;br /&gt;&lt;h4&gt;andThen&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;You would think that f1 &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;andThen&lt;/span&gt;&lt;/tt&gt; f2 should be defined only in the cases when the results of f1 are defined in f2&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;doubler&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PartialFunction&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;,&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;contains&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doubler&lt;/span&gt; &lt;span class="n"&gt;andThen&lt;/span&gt; &lt;span class="n"&gt;doubler&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Of course, that's not how it works. In order to find out if the output of f1 is a valid input for f2, we would need to execute the function, and it's better not to do this in case it has side effects. This means that we cannot rely on calling isDefined for the combined function to avoid &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;MatchError&lt;/span&gt;&lt;/tt&gt;s:&lt;/p&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;&amp;gt; f isDefinedAt 2&lt;br /&gt;res3: Boolean = true&lt;br /&gt;&amp;gt; f(2)&lt;br /&gt;scala.MatchError: 4&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Conclusion: when you're looking for performance, it always help to understand how the abstractions you're using decompose into simpler building blocks.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-1810350731474102891?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/1810350731474102891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=1810350731474102891' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/1810350731474102891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/1810350731474102891'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2011/07/partially-unexpected-effects-of.html' title='Partially unexpected effects of chaining partial functions in Scala'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-967432484183074290</id><published>2011-06-17T15:04:00.001+03:00</published><updated>2011-06-17T15:05:38.571+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lift'/><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='akka'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Testing actors in Scala</title><content type='html'>&lt;p&gt;Probably the most frequent question that people asked on Scala eXchange 2011 was how to test actors. Since I've long planned to write up a blog post on this topic, this was an indication that it's high time to get it done.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;It seems that the main problem people have is that actors are asynchronous and this introduces non-determinism in their tests. How do you know when to check if the actor has received and processed the message? Do you just wait a certain number of seconds before checking? This would make tests unnecessarily slow.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Another problem I think folks have is that they don't know how to verify that an actor has sent a message to another actor. Developers are familiar with mocking objects to verify that a method has been called, but how do you mock an actor to verify it has received a certain message?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Finally, it is difficult for most to handle the fact that it's not easy (or at least not idiomatic) to check the actor's internal state. This is especially valid with Akka actors which are created using a factory method and you can't define methods for mucking with the actor's internals.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Let me first address the last one. How do you check that internal state of an actor has changed? You don't! I find that actors are better at following the Object-Oriented principle of encapsulation even than objects are. Relying on a certain internal state couples your tests unnecessarily to the implementation and makes them brittle. As Viktor Klang has pointed out, if the internal state of an actor cannot be observed outside the actor, does it really matter what it is?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So how do you know when an actor has processed a message which was sent asynchronously? An easy way to eliminate non-determinism is to define a method where the functionality is located and call that upon receiving a message:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;MyActor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;computation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="o"&gt;...&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;result&lt;/span&gt;&lt;br /&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyActor&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Actor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="n"&gt;loop&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;react&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class="n"&gt;anotherActor&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="n"&gt;computation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Then you can test the method the way you are familiar with. Putting the method in the companion object means that you can't test the internal state- but this also means this approach should work with Akka actors as well. We also avoid the problem of checking if the next actor in the chain has received the result.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sometimes you cannot test a helper method and sometimes testing the method is not enough. In these cases you want to verify explicitly that an actor has sent a message to another actor as a result of receiving a certain trigger message. Here's another approach we use at &lt;a class="reference external" href="http://svn.apache.org/repos/asf/esme/trunk/server/src/test/scala/org/apache/esme/api/TwitterAPITest.scala"&gt;Apache ESME&lt;/a&gt;, which works very well:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;Wait&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConductorActor&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Actor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="n"&gt;react&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Wait&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;receive&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MessageReceived&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;br /&gt;        &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;What's going on here? We define a helper actor (the recipient) which is the one supposed to receive the message from the actor we want to test (the sender). Usually the sender we want to test doesn't send a message to a hardcoded recipient- it is a good idea to either inject it as a construction parameter at instantiation time or register it via a message representing a subscription request.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This actor uses a fairly rarely used nested syntax, which is only available with the actors in the standard Scala library. The recipient handler would reply synchronously (which is what we want) with the message received only after we give it the signal that we've already sent a message to the sender. This implementation also relies on the fact that unhandled messages are kept in the inbox if there's no handler for them. While this can lead to memory leaks if these messages don't get handled, it is a nice way to process out-of-order messages, which is something we take advantage of here. This is similar to selective receive in Erlang and is a fairly painless way to handle race conditions- it doesn't matter which message has been received first here.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;These features are not present in Akka, but you could emulate nested handlers using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;become&lt;/span&gt;&lt;/tt&gt; and keep unhandled messages using. An even better idea would be to use the built-in TestKit or the akka-expect project, which use the same technique in a not so ad-hoc manner (but AFAIK don't work for non-Akka actors).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So now the only thing we need to do is send the trigger message to the tested sender and then ask the recipient if the resulting message has been sent by the sender:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="c1"&gt;// wait till the message appears in the timeline&lt;br /&gt;// or fail after 5 seconds&lt;br /&gt;&lt;/span&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;msgReceived&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conductor&lt;/span&gt; &lt;span class="o"&gt;!?&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Wait&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msgReceived&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;fail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;no message received&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;If the recipient gets the message within a certain timeframe, the test is successful, otherwise we time out and fail the test. The nice thing about this approach is that in the happy path case, the test can continue immediately without slowing down the test suite. The test is slowed down by the designated timeout only when the test is going to fail, but this should be an exceptional event.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A minor inconvenience is if the sender doesn't expect the recipient to be a Scala library actor, but e.g. a Lift actor, but this can be easily overcome by using a bridge actor, which only acts as an intermediary and just forwards the request to the designated recipient actor:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BridgeActor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Actor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;LiftActor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;messageHandler&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;nm&lt;/span&gt; &lt;span class="k"&gt;&amp;#64;&lt;/span&gt; &lt;span class="nc"&gt;MessageReceived&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="n"&gt;nm&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;liftActor&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BridgeActor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conductor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="nc"&gt;Distributor&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nc"&gt;Listen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;liftActor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="nc"&gt;Distributor&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nc"&gt;Listen&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;followerUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;liftActor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Here we're injecting one actor as a construction parameter and registering another via the Listen message.&lt;/p&gt;&lt;br /&gt;&lt;div class="section" id="further-research"&gt;&lt;br /&gt;&lt;h4&gt;Further research&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;If you're using Akka, your best bet is the recommended TestKit- here's an article on how to use it:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a class="reference external" href="http://roestenburg.agilesquad.com/2011/02/unit-testing-akka-actors-with-testkit_12.html"&gt;http://roestenburg.agilesquad.com/2011/02/unit-testing-akka-actors-with-testkit_12.html&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Another solution would be to use the akka-expect framework:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/joda/akka-expect"&gt;https://github.com/joda/akka-expect&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;A more universal library is Awaitility, which uses a similar solution, but with more general applicability to Java threads and Scala actors:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a class="reference external" href="http://code.google.com/p/awaitility/"&gt;http://code.google.com/p/awaitility/&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;ScalaTest and Specs also have the conductor actor, which implement a similar idea of using a CountDownLatch to make actors deterministic:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.scalatest.org/scaladoc/doc-1.0/org/scalatest/concurrent/Conductor.html"&gt;http://www.scalatest.org/scaladoc/doc-1.0/org/scalatest/concurrent/Conductor.html&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-967432484183074290?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/967432484183074290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=967432484183074290' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/967432484183074290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/967432484183074290'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2011/06/testing-actors-in-scala.html' title='Testing actors in Scala'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-7507994899564414295</id><published>2010-10-21T00:00:00.002+03:00</published><updated>2010-10-21T13:46:40.255+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='option'/><category scheme='http://www.blogger.com/atom/ns#' term='null'/><category scheme='http://www.blogger.com/atom/ns#' term='fantom'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Why Scala's Option won't save you from lack of experience</title><content type='html'>Some time ago &lt;a class="reference external" href="http://twitter.com/cbeust"&gt;Cedric Beust&lt;/a&gt; was the cause for some excitement in the Scala community by declaring that &lt;a class="reference external" href="http://beust.com/weblog/2010/07/28/why-scalas-option-and-haskells-maybe-types-wont-save-you-from-null/"&gt;he doesn't see the advantages of using Scala's Option type&lt;/a&gt;, which is also similar to Haskell's &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Maybe&lt;/span&gt;&lt;/tt&gt; type.&lt;br /&gt;&lt;br /&gt;There were a lot of insightful comments which outlined the benefits of using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;. James Iry has written a well-reasoned post called &lt;a class="reference external" href="http://james-iry.blogspot.com/2010/08/why-scalas-and-haskells-types-will-save.html"&gt;Why Scala's &amp;quot;Option&amp;quot; and Haskell's &amp;quot;Maybe&amp;quot; types will save you from null&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I wanted to approach things differently. I wanted to show people some patterns which usually come with experience and let them decide which is better. That's why this turned into a very long post which looks more like a tutorial. Of course, I'm not adding anything new to the discussion, but just summarizing some of the &lt;a class="reference external" href="http://blog.lostlake.org/index.php?/archives/50-The-Scala-Option-class-and-how-lift-uses-it.html"&gt;common wisdom&lt;/a&gt; accumulated by the community. I'm sure this is not the last typical blog post showing the wonders of Option, but I hope it can clear up some (Some?) misunderstandings. Or Maybe not.&lt;br /&gt;&lt;br /&gt;But more importantly, I wanted to explain why having a solution as a language feature is a premature optimization. It's neither as flexible, nor as powerful as having it as just a type in the library.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;NullPointerException&lt;/h4&gt;&lt;br /&gt;Cedric is definitely not alone- programmers who decide to give Scala a try (and moreso Haskell or the ML family) face conceptual differences from popular imperative languages. Just reading that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; is a type wrapper does not mean it's easy to wrap one's head around it.&lt;br /&gt;&lt;br /&gt;One advantage of using Scala is that if you are convinced that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;NullPointerExceptions&lt;/span&gt;&lt;/tt&gt; solve your problem better, you are free to use it. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; is just one option. And of course, you can come back later any time if you make up your mind that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; has Some advantages (e.g. composability). Of course, some might view having too many choices as a disadvantage.&lt;br /&gt;&lt;br /&gt;But both Scala and Clojure must live with the design decisions on the JVM which were taken before them, and with interoperating with a wealth of existing libraries. So allowing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;null&lt;/span&gt;&lt;/tt&gt; is first of all a practical decision.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Getting started&lt;/h4&gt;&lt;br /&gt;First of all, let's define a simplistic employee type, a list of employees, and a map where the &amp;quot;builder&amp;quot; occupation points to the list of employees.&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;bob&amp;#64;builder.com&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;builder&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Compile-time safety and backward compatibility&lt;/h4&gt;&lt;br /&gt;One of the examples given by Cedric is pattern matching on an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; type. His main point of contention is that this looks very much like testing for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;null&lt;/span&gt;&lt;/tt&gt;. Except one minor point: where is the example similar to the case when you &lt;em&gt;don't&lt;/em&gt; want to test for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;null&lt;/span&gt;&lt;/tt&gt;?&lt;br /&gt;&lt;br /&gt;Exactly. No such valid example exists if you want to use the value inside &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;, at least not unless you're explicit about it. As &lt;a class="reference external" href="http://twitter.com/psnively"&gt;Paul Snively&lt;/a&gt; mentions, the compiler will stop you. Cedric has noticed, &amp;quot;the worst part about this example is that it forces me to deal with the null case right here&amp;quot;. But this is not the worst part, it's maybe the best part.&lt;br /&gt;&lt;br /&gt;Do you remember a feature which was added to Java 5, which was intended to save you from another type of exception, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ClassCastException&lt;/span&gt;&lt;/tt&gt;? Of course, that would be generics! The problem is, it gives you type-safety, but only as long as you use classes compiled with the Java 5 compiler &lt;em&gt;and&lt;/em&gt; you don't use the escape hatch of raw types. As soon as you start using legacy code, you leave the safety of compiler checked code. You can ignore the warnings at your own risk, because then there's no guarantee you won't get a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ClassCastException&lt;/span&gt;&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;Does this remind you of something? Compile-time safety as long as you don't use legacy code or the escape hatch? These restrictions sound exactly like the ones &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; has.&lt;br /&gt;&lt;br /&gt;And of course, there is an escape hatch. You can use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option.get&lt;/span&gt;&lt;/tt&gt; or instead of pattern matching, you can even use your old friend the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;if&lt;/span&gt;&lt;/tt&gt; statement (Scala veterans, please close your eyes &lt;em&gt;now&lt;/em&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;evangelists&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;evangelist&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// ugly, ugly, ugly&lt;br /&gt;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;evangelists&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;No such occupation here!&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Found occupation &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;evangelists&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But, as you'll see later, this doesn't mean that you have to deal with the &amp;quot;no value&amp;quot; case right here. Pattern matching is not the only option.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Simplification through a generalization&lt;/h4&gt;&lt;br /&gt;Instead of solving the most obvious problem, it always pays out to see if it isn't a manifestation of a bigger class of problems. Having a related class of problems solved by a common pattern simplifies things. There are fewer rules to remember. Not only that, but the specific applications of the general solution begin to interact in ways you couldn't have anticipated before. Eventually problems will appear which would be solved by a general solution, problems which you didn't know about when you implemented the solution.&lt;br /&gt;&lt;br /&gt;As it turns out, the problem of &lt;a class="reference external" href="http://daily-scala.blogspot.com/2010/01/more-on-null-to-option-conversion.html"&gt;syntax similar to the safe dereference operator&lt;/a&gt; can be solved in Scala. I would say that having no explicit syntax for this, it's a fairly elegant solution, but this is subjective opinion.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Handling both value and lack of value and stop processing&lt;/h4&gt;&lt;br /&gt;This is handled by our well-known pattern match. It seems easy to use and obvious in what it does.&lt;br /&gt;&lt;br /&gt;The advantage of pattern matching is that it uses the type system in such a way that forgetting to handle one of the cases explicitly will result in a compile time warning.&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="n"&gt;occupations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;builder&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;builder occupation exists&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="c1"&gt;// oops, forgot to check for None or the catch-all _&lt;br /&gt;&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// warning: match is not exhaustive!&lt;br /&gt;// missing combination           None&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The disadvantage is that pattern matching doesn't compose very elegantly. If the result of the pattern match is just an intermediate step, you'll need to add another one, and another, and pattern matching does take some screen real estate.&lt;br /&gt;&lt;br /&gt;Pattern matching is a bit like exception handling with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;try&lt;/span&gt;&lt;/tt&gt;/&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;catch&lt;/span&gt;&lt;/tt&gt; blocks- you usually do it when you're interested in both the normal behaviour and the exceptional behaviour and that's fairly verbose. On a related note, did you know that you can use pattern matching in Scala's exception handlers?&lt;br /&gt;&lt;br /&gt;So let's see what we can do to get more composable data processing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Transform value&lt;/h4&gt;&lt;br /&gt;When we're interested in creating a series of steps for processing a value, we can use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;map&lt;/span&gt;&lt;/tt&gt;. It will transform the value if it's there, but will leave it inside the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;. And &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;map&lt;/span&gt;&lt;/tt&gt; won't change the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; if it's empty (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;None.map&lt;/span&gt;&lt;/tt&gt; will result in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/tt&gt;).&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// Some(Person(bob,bob&amp;#64;builder.com))&lt;br /&gt;&lt;/span&gt;&lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// Some(bob&amp;#64;builder.com)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you need to &amp;quot;flatten&amp;quot; the result you can use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flatMap&lt;/span&gt;&lt;/tt&gt;. This means that instead of an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; nested inside an &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;, you get just one &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;. It only results in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Some&lt;/span&gt;&lt;/tt&gt; (a &amp;quot;full&amp;quot; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; type) if it's called on &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Some&lt;/span&gt;&lt;/tt&gt; and also results in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Some&lt;/span&gt;&lt;/tt&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;builders&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;builder&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// Some(List(Person(bob,bob&amp;#64;builder.com)))&lt;br /&gt;&lt;/span&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;bobTheBuilder&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builders&lt;/span&gt; &lt;span class="n"&gt;flatMap&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// Some(Person(bob,bob&amp;#64;builder.com))&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you were using just &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;map&lt;/span&gt;&lt;/tt&gt;, you would get &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Some(Some(Person(bob,bob&amp;#64;builder.com)))&lt;/span&gt;&lt;/tt&gt;, which is probably a bit too nested for your taste.&lt;br /&gt;&lt;br /&gt;Some of you are probably familiar with other languages which have &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;map&lt;/span&gt;&lt;/tt&gt; (like Ruby or Python) and are scratching their heads: &amp;quot;Wait, wasn't &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;map&lt;/span&gt;&lt;/tt&gt; defined only for lists/&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Enumerable&lt;/span&gt;&lt;/tt&gt;s?&amp;quot;. Please be patient.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Only get the value if it satisfies a test&lt;/h4&gt;&lt;br /&gt;If you find only some of the possible values useful, you can weed out what you have by using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;filter&lt;/span&gt;&lt;/tt&gt;. It will only result in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Some&lt;/span&gt;&lt;/tt&gt; for values which satisfy a certain condition (called a &lt;em&gt;predicate&lt;/em&gt;).&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="n"&gt;bobTheBuilder&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="n"&gt;endsWith&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;builder.com&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// Some(Person(bob,bob&amp;#64;builder.com))&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I'm sure at this point the folks who have used Google Collections have also joined the folks with past Ruby or Python experience screaming: &amp;quot;Hey, but filter is only used for Collections!&amp;quot;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Transform lack of value&lt;/h4&gt;&lt;br /&gt;That's fine, but eventually you want to get the value out. If there's no value, just assume some default value. We have to use pattern matching again, right?&lt;br /&gt;&lt;br /&gt;But there is a shorter solution. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;getOrElse&lt;/span&gt;&lt;/tt&gt; extracts the value or puts a default value of the same type if there's nothing in the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; container:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;larryWho&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;larry&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// None&lt;br /&gt;&lt;/span&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;emptyEmail&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;larryWho&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="c1"&gt;// None&lt;br /&gt;&lt;/span&gt;&lt;span class="n"&gt;emptyEmail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getOrElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;nobody&amp;#64;nowhere.com&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// nobody&amp;#64;nowhere.com&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Groovy has this in the form of the Elvis operator. The trouble is, you can't get rid of the elvis operator, it's just adding cruft to the language, even though it's a useful one. It's also somewhat restrictive that it's all this operator can do.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Chain, chain, chain&lt;/h4&gt;&lt;br /&gt;The reason &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;map&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flatMap&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;filter&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;getOrElse&lt;/span&gt;&lt;/tt&gt; are so useful is that they can be chained together, intermixed and the results can be passed around to other methods.&lt;br /&gt;&lt;br /&gt;Let's shift to high gear and put it all together:&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="n"&gt;occupations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;builder&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;flatMap&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;}.&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="n"&gt;endsWith&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;builder.com&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;}.&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;getOrElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;nobody&amp;#64;nowhere.com&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// bob&amp;#64;builder.com&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If we're not yet interested in which step processing has failed, this is a clear way to express the process flow. It's also similar to the Fantom example Cedric desribed.&lt;br /&gt;&lt;br /&gt;There is an ever shorter syntax for this using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/tt&gt; expressions (or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/tt&gt; comprehensions).&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builders&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;builder&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;br /&gt;      &lt;span class="n"&gt;bobTheBuilder&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;builders&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;br /&gt;      &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bobTheBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="n"&gt;endsWith&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;builder.com&amp;quot;&lt;/span&gt;&lt;br /&gt;      &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;br /&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="n"&gt;getOrElse&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;nobody&amp;#64;nowhere.com&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// bob&amp;#64;builder.com&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But wait, weren't &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/tt&gt; expressions a way to loop over stuff? Well, yes, this too. More generally, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/tt&gt; expressions work with collections. And the beauty of it all is that we can use collections together with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; and do nested invocations. Let's modify the example a bit and suppose that there might be more than one person named Bob and we want them all.&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builders&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;builder&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span class="n"&gt;bobTheBuilder&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;builders&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bobTheBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bobTheBuilder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="n"&gt;endsWith&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;builder.com&amp;quot;&lt;/span&gt;&lt;br /&gt;     &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// List(bob&amp;#64;builder.com)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Because for all practical purposes, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; behaves like a specialized collection. By viewing it as one, you reuse the experience of all the programmers using Groovy, Ruby, Python, Google Collections and whatnot, and flatten the learning curve.&lt;br /&gt;&lt;br /&gt;Now imagine that the only way to work with a collection is to pattern match it. Would you use it? Yeah, me neither.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Safe invoke and composability&lt;/h4&gt;&lt;br /&gt;Now let's see how &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;filter&lt;/span&gt;&lt;/tt&gt; works in Fantom:&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;fansh&amp;gt; list := [1, 2, null]&lt;br /&gt;fansh&amp;gt; list.findAll |v| { v.isEven }&lt;br /&gt;sys::NullErr: java.lang.NullPointerException&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Oh crap, then I need to to use the safe invoke operator:&lt;br /&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;fansh&amp;gt; list.findAll |v| { v?.isEven }&lt;br /&gt;ERROR(20): Cannot return 'sys::Bool?' as 'sys::Bool'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But it all results in a compile-time error. It's the same story with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;reduce&lt;/span&gt;&lt;/tt&gt; higher-order function:&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;fansh&amp;gt; list.reduce(0) |r, v| { v + r }&lt;br /&gt;sys::NullErr: java.lang.NullPointerException&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So I can't practically use the safe invoke operator in nullable collections with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;filter&lt;/span&gt;&lt;/tt&gt;/&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;reduce&lt;/span&gt;&lt;/tt&gt;, which the Fantom documentation has conveniently omitted from the &lt;a class="reference external" href="http://fantom.org/doc/examples/sys-lists.html"&gt;documentation page&lt;/a&gt;. So we're back to checking for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;null&lt;/span&gt;&lt;/tt&gt; the old way. This means that unlike &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flatMap&lt;/span&gt;&lt;/tt&gt;, the safe invoke works fine when you chain, but not when you compose.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Iterator&lt;/h4&gt;&lt;br /&gt;Let's now see some other advantages of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; behaving like a collection. For instance, it lets you use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Iterable&lt;/span&gt;&lt;/tt&gt;'s API in some &lt;a class="reference external" href="http://daily-scala.blogspot.com/2010/04/quick-note.html"&gt;elegant&lt;/a&gt; ways:&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;noVal&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="n"&gt;someVal&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;someVal&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;noVal&lt;/span&gt;&lt;br /&gt;&lt;span class="c1"&gt;// List(1, 2, 3, 4)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Guess what happens here? Only the numbers contained in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Some&lt;/span&gt;&lt;/tt&gt; are added to the list. I think there's no operator for this in Fantom and Groovy, and it would be overkill to include one, too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;One size doesn't fit all&lt;/h4&gt;&lt;br /&gt;Wait, if &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; is like a collection, does this mean that there are many types of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;? Does this mean I can create my &lt;em&gt;own&lt;/em&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;?&lt;br /&gt;&lt;br /&gt;Yes, and &lt;em&gt;yes&lt;/em&gt;. Just as there isn't just one type of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;List&lt;/span&gt;&lt;/tt&gt;, or one type of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Map&lt;/span&gt;&lt;/tt&gt;, there can also be several types of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;. For instance, &lt;a class="reference external" href="http://lift.la/scala-option-lift-box-and-how-to-make-your-co"&gt;Lift defines its own&lt;/a&gt;, which it currently calls &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Box&lt;/span&gt;&lt;/tt&gt; (I think it's a great metaphor). One of the things &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Box&lt;/span&gt;&lt;/tt&gt; has in addition to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; is a type to collect &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Failure&lt;/span&gt;&lt;/tt&gt;s. It's no longer just a &amp;quot;dunno what happened, something failed along the way&amp;quot;. It's a list of error messages which can pinpoint exactly what went wrong. This is invaluable for a web framework, because when a user expects a complex form to be validated, a simple &amp;quot;some of our input is wrong&amp;quot; just won't cut it.&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?~&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;id param missing&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;~&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?~&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;User not found&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toXml&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And guess what, you can also &lt;a class="reference external" href="http://speaking-my-language.blogspot.com/2010/08/testing-with-lifts-testframework.html"&gt;define your own operators&lt;/a&gt;, which also work in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/tt&gt; comprehensions.&lt;br /&gt;&lt;pre class="code-block scala literal-block"&gt;&lt;br /&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/account/verify_credentials.xml&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Nil&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="o"&gt;!&amp;#64;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Failed to log in&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/statuses/update.xml&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;status&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;test_msg1&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="o"&gt;!&amp;#64;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Couldn't post message&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="n"&gt;xml&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xml&lt;/span&gt;&lt;br /&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;xml&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Except that they're not operators. When conventions and patterns evolve, Lift folks can always change the &amp;quot;operator&amp;quot;. Or another framework can do it.&lt;br /&gt;&lt;br /&gt;Another good example of using an enhanced &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; is Josh Suereth's (jsuereth) &lt;a class="reference external" href="http://github.com/jsuereth/scala-arm"&gt;Scala ARM library&lt;/a&gt;. It's collecting a list of errors, and Java's safe resource blocks proposed for Java 7 looks primitive in comparison.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Option is not only Scala's to have&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Actually, there's nothing specific about &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; that ties it to Scala. The only thing which is Scala specific is the syntax sugar of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/tt&gt; comprehensions. You can use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt; in Java if you want, although some of the examples above wouldn't be as concise and so it might be a bit of a pain. But this doesn't stop people from &lt;a class="reference external" href="http://blog.tmorris.net/maybe-in-java"&gt;trying to recreate&lt;/a&gt; &lt;a class="reference external" href="http://blog.tmorris.net/maybe-monad-in-java"&gt;Maybe in Java&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Many folks have even &lt;a class="reference external" href="http://www.natpryce.com/articles/000776.html"&gt;tried to cheat&lt;/a&gt; and &lt;a class="reference external" href="http://codemonkeyism.com/for-hack-with-option-monad-in-java/"&gt;use Java's enhanced for expression&lt;/a&gt; as &lt;a class="reference external" href="http://eng.kaching.com/2010/05/better-option-for-java.html"&gt;syntax sugar&lt;/a&gt;. So if Java can afford some syntax sugar over &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Iterator&lt;/span&gt;&lt;/tt&gt;, and according to Joshua Bloch the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/tt&gt; expression is a clear win, why shouldn't Scala do it? The difference is only that Scala's is applicable to a wider set of problems.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Why language syntax won't save you from the future&lt;/h4&gt;&lt;br /&gt;One advantage which some people don't realize Scala has is that it's a relatively minimal language with a relatively rich library. Apart from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Option&lt;/span&gt;&lt;/tt&gt;, there are other examples where having a library instead of a language feature has brought huge benefits to Scala. One such example is actors.&lt;br /&gt;&lt;br /&gt;Let's compare Scala's actors to Erlang's. Undoubtedly Erlang is the daddy of practical actor implementations. Actors in the Erlang virtual machine have some superb characteristics which other runtime implementations will have a hard time catching up with. They're scalable and lightweight. They work across hosts and in the same virtual machine. They can be hot swapped and you can create millions of them in a single virtual machine.&lt;br /&gt;&lt;br /&gt;But there's only one type of actor. This means it must deal with all possible cases, and as it usually happens, it deals better with some and worse with others. I have no doubt that having actors as part of the language, choosing only one type of actor is a very sensible decision, but it can still be restrictive sometimes.&lt;br /&gt;&lt;br /&gt;Scala deals with this differently. Scala's actors are not part of the language, and the actor message send syntax (which is borrowed from Erlang) is just a method invocation in a library. This means that Scala's free to evolve different actor implementation, and you're free to choose the one which suits your case better. Some are more full-featured, some are lightweight and performant; some are remote, some are local; some use a thread pools, some use a single scheduler; some use managed hierarchies, some don't. Regarding actors Scala the language is smaller than Erlang, but the Scala libraries are richer.&lt;br /&gt;&lt;br /&gt;Which actor library will win? I don't know. And probably neither do you. There might not be one best answer. That's why hardcoding stuff in the language is not a good way to prepare for the future. Only experience will, either the collective experience of the community or the extensive experience of a genius Benevolent Dictator For Life.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-7507994899564414295?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/7507994899564414295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=7507994899564414295' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7507994899564414295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7507994899564414295'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2010/08/why-scalas-option-wont-save-you-from.html' title='Why Scala&apos;s Option won&apos;t save you from lack of experience'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-472031421749933237</id><published>2010-09-11T23:00:00.004+03:00</published><updated>2010-10-22T11:08:33.756+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='screen'/><title type='text'>Top 5 underused GNU screen features</title><content type='html'>&lt;p&gt;Most people use &lt;a class="reference external" href="http://en.wikipedia.org/wiki/GNU_Screen"&gt;GNU screen&lt;/a&gt; mostly for its abilities to detach from the terminal and create multiple shell sessions. This makes it ideal in combination with remote terminal connections like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ssh&lt;/span&gt;&lt;/tt&gt;. There are some features which, although not very popular, are still useful on a number of occasions.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;As a bonus, let's start with a short explanation of the popular features. If you're familiar with detaching and multiplexing, you might want to skip to the sections about more rarely used features.&lt;/p&gt;&lt;br /&gt;&lt;div class="section" id="detaching"&gt;&lt;br /&gt;&lt;h4&gt;Detaching&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;The first thing to know about &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; is that all shortcuts start with Ctrl + A by default.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The most common &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; workflow is:&lt;/p&gt;&lt;br /&gt;&lt;ol class="arabic"&gt;&lt;br /&gt;&lt;li&gt;&lt;p class="first"&gt;Connect to a remote system via &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ssh&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p class="first"&gt;Start/attach &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;screen -D -RR&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;This command will detach a running &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; session and create a new one, if necessary.&lt;/p&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p class="first"&gt;Work&lt;/p&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;p class="first"&gt;Detach &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; by pressing Ctrl + A, then D.&lt;/p&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p class="first"&gt;Disconnect.&lt;/p&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p class="first"&gt;Take a break, return to 1 :)&lt;/p&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;You can find the currently running &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; sessions using the command:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;screen -ls&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Nohup"&gt;nohup&lt;/a&gt; is also used when you want to detach a program when you disconnect, but it will never attach to the terminal, so you cannot use it if it's interactive.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section" id="multiplexing"&gt;&lt;br /&gt;&lt;h4&gt;Multiplexing&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;When you connect via &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ssh&lt;/span&gt;&lt;/tt&gt;, one shell is rarely enough. Connecting a second time is often inconvenient and slow. Enter &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt;- you can create a new session using Ctrl + A, then C. You switch to the next one using Ctrl + A, then space (or n). You switch to the previous one using Ctrl + A, then backspace (or p). Using Ctrl + A and then a digit you can directly jump to the session numbered 0-9.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ssh&lt;/span&gt;&lt;/tt&gt;'s option &lt;a class="reference external" href="http://www.debian-administration.org/articles/290"&gt;ControlMaster&lt;/a&gt; will reuse an existing connection and open another shell immediately, but this is only relevant for &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ssh&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now you know the basics, let's see what other goodies &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; offers.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section" id="sharing-sessions"&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;1. Sharing sessions&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Typing in a terminal is usually a lonely experience. Sometimes you wish that you could show someone else what you're doing or even do it together. It might be because you want to teach someone some UNIX tricks, or you must solve an issue together or you're up to the challenge of remote pair programming. Your wish is granted! In &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt;, you can make it so that your keyboards and monitors are in control of a single session.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; host should do the following:&lt;/p&gt;&lt;br /&gt;&lt;ol class="arabic"&gt;&lt;br /&gt;&lt;li&gt;&lt;p class="first"&gt;Ctrl + A then type:&lt;/p&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;:multiuser on&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;p class="first"&gt;Ctrl + A then type:&lt;/p&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;:acladd guest&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;where &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;guest&lt;/span&gt;&lt;/tt&gt; is the name of the user you want to let in your session&lt;/p&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;Then the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; guest can join using the following command (which will work if there's a single multi-user session open):&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="literal-block"&gt;&lt;br /&gt;screen -x username/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: VNC can be used only for graphical remote connection sharing.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section" id="copy-and-paste"&gt;&lt;br /&gt;&lt;h4&gt;2. Copy and paste&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;It's not always easy to copy and paste text in a terminal. For one, if you're on a getty console (the black screen with the login prompt and no graphics), you can't even use your mouse (usually). If you have a crappy X terminal, you might have the problem that wrapped lines are cut by newlines or it's hard to select the output if it spans more than a single screen... Whatever it is, with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; you can cut like a pro without even using the mouse.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ctrl + A, then pressing &amp;quot;[&amp;quot; will enter copy mode. When in copy mode, you navigate around using the vi key shortcuts (you know the vi shortcuts, otherwise you wouldn't be reading about working in terminal sessions, right?).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Press space once to mark the beginning and a second time to mark the end of the snippet you want to cut.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Ctrl + A, then &amp;quot;]&amp;quot; will paste the copied text.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Did I mention &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; can also copy rectangular blocks of text? Reading about it in the manual is left as an exercise for the curious reader.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: X-Server's select/middle-click can be used- only if you're running in an X session, though.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section" id="log-output"&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;3. Log output&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;We humans are not good at remembering stuff, that's what computers are for. To record exactly what you have typed and what was the output, start logging using Ctrl + A, then H, and the same sequence to stop logging. The logging session is written to screenlog.0 if you're recording in the first window, screenlog.1 in the second one, etc.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: The UNIX command &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;script&lt;/span&gt;&lt;/tt&gt; will start a new shell and record all keystrokes and output in the file &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;typescript&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section" id="monitor-for-activity"&gt;&lt;br /&gt;&lt;h4&gt;4. Monitor for activity&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Let's say you've started a long-running command and you're waiting for it to finish while you're busy typing in another window. Switching the window periodically just to check what's going on quickly becomes annoying, so you type Ctrl + A, then M and you're set- &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; is watching the console for you. If anything changes in this window, you will see a notification in the status line at the bottom.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: Many linux terminals can monitor for activity, e.g. konsole- but they're graphical and need to run in an X session.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section" id="lock-screen"&gt;&lt;br /&gt;&lt;h4&gt;5. Lock screen&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;It's often useful to lock the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; session without detaching, especially when using a multi-user session. Ctrl + A, then x, and you're done. Type your password and your session is available again.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: Popular desktop environments use xscreensaver, but again- this only works in X sessions.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="section" id="where-to-go-from-here"&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Where to go from here?&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;If you like GNU screen, you might also try &lt;a class="reference external" href="http://tmux.sourceforge.net/"&gt;tmux&lt;/a&gt;. According to the site, &amp;quot;tmux is intended to be a modern, BSD-licensed alternative to programs such as GNU screen&amp;quot;. If you're interested, check out this detailed &lt;a class="reference external" href="http://blog.hawkhost.com/2010/06/28/tmux-the-terminal-multiplexer/"&gt;tmux blog post&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you want to take &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; to the next level, you might give tiling window managers a try. They do for the graphical environment what &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/tt&gt; does for the terminal. The idea is that you don't resize your windows, but the window manager does that automatically by partitioning the desktop area in adjacent windows. Most of these also try to use keyboard shortcuts extensively and obviate the need of a mouse. I'm currently impressed by &lt;a class="reference external" href="http://xmonad.org/"&gt;xmonad&lt;/a&gt;, although I've heard nice things about the &lt;a class="reference external" href="http://awesome.naquadah.org/"&gt;awesome&lt;/a&gt; window manager as well (yes, that's its name).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-472031421749933237?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/472031421749933237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=472031421749933237' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/472031421749933237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/472031421749933237'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2010/09/top-5-underused-gnu-screen-features.html' title='Top 5 underused GNU screen features'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-689612238461722825</id><published>2010-08-10T23:01:00.010+03:00</published><updated>2010-08-12T06:02:39.472+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testframework'/><category scheme='http://www.blogger.com/atom/ns#' term='lift'/><title type='text'>Testing with Lift's TestFramework</title><content type='html'>&lt;h4&gt;Getting started&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;HTTP testing is sufficiently tedious that some folks don't do it. Even if we do it, in Java it doesn't look as pretty as it could be.&lt;br /&gt;&lt;br /&gt;The Scala &lt;a href="http://liftweb.net"&gt;Lift&lt;/a&gt; web framework, apart from the other advantages it has (which are a topic for many a blog post) offers some syntax-sugar wrappers so that testing of our REST APIs can be concise and to the point.&lt;br /&gt;&lt;br /&gt;Combined with Jetty, this leads to some seriously short and readable code.&lt;br /&gt;&lt;br /&gt;First, we need to:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;use the trait "with TestKit" in our test&lt;/li&gt;&lt;br /&gt;&lt;li&gt;override the &lt;tt&gt;baseUrl&lt;/tt&gt; property&lt;/li&gt;&lt;br /&gt;&lt;li&gt;start our Jetty server&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/517968.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Then if we want to output our own failure message later, we need to provide an implicit class of type &lt;tt&gt;ReportFailure&lt;/tt&gt;, where we only need to implement the &lt;tt&gt;fail&lt;/tt&gt; method, which predictably takes a &lt;tt&gt;String&lt;/tt&gt;. For example, regardless of whether we use ScalaTest or Specs, we can fall back to the &lt;tt&gt;fail&lt;/tt&gt; method which is inherited by our test class:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/517975.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;This is all we need so far.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Using it&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Now we're ready to GET some action.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/518049.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;There's already a lot going on here. First of all, the &lt;tt&gt;get&lt;/tt&gt; and &lt;tt&gt;post&lt;/tt&gt; methods return a &lt;tt&gt;TestResponse&lt;/tt&gt; (you don't see it, because it's inferred). And the nice thing about &lt;tt&gt;TestResponse&lt;/tt&gt; (and Scala) is that since it implements the &lt;tt&gt;foreach&lt;/tt&gt; method, it can be used in &lt;tt&gt;for&lt;/tt&gt; expressions together with the "&lt;-" symbol.&lt;br /&gt;&lt;br /&gt;Whatever is extracted by the &lt;tt&gt;for&lt;/tt&gt; expression can be used to issue &lt;tt&gt;get&lt;/tt&gt; and &lt;tt&gt;post&lt;/tt&gt; requests, but in the context of the previous request. This means that cookies are preserved, so you can use the same HTTP session. In this contrived example we use an &lt;tt&gt;httpClient&lt;/tt&gt; as an argument to the &lt;tt&gt;get&lt;/tt&gt; method (which is supposed to use some HTTP credentials and log us in). In the following call, we don't need to use the authenticating http client, because we can have our cookies (and eat them, too).&lt;br /&gt;&lt;br /&gt;We can also use http parameters as a sequence of tuples, which can be delimited using the "-&gt;" operator.&lt;br /&gt;&lt;br /&gt;For any &lt;tt&gt;TestResponse,&lt;/tt&gt; we can use the &lt;tt&gt;xml&lt;/tt&gt; property, which is the XML as a &lt;tt&gt;scala.xml.Elem&lt;/tt&gt; wrapped in the (ubiquitous for Lift) &lt;tt&gt;Box&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;Finally, there's concise syntax to assert certain properties about the response. For example the "!@" operator checks if the response code is 200, otherwise it fails with the error message specified after the operator.&lt;br /&gt;&lt;br /&gt;If we expect a specific return code other than 200, we can also specify it explicitly:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/518082.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Customizing&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;If you want to define a HTTP basic authentication client to be used by default by your requests, you can override the method &lt;tt&gt;theHttpClient&lt;/tt&gt;. Lift's &lt;tt&gt;TestFramework&lt;/tt&gt; provides the &lt;tt&gt;buildBasicAuthClient&lt;/tt&gt; method, which can be reused to quickly create an HTTP client with a set user and password.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/518088.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;If you're like me, you might lose hours trying to find out why the request doesn't work when the server doesn't explicitly request authentication. Then setting the preemptive flag on the client would definitely save some time.&lt;br /&gt;&lt;br /&gt;I know some of you Scala geeks are already bored because everything so far is just so simple. There wasn't even any mention of implicits! But rest assured, I will find some use for implicits.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Pimping&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;The usage snippet in the for expression above is not quite right. If the response contains no valid xml, then the specs matcher will not be executed and the test will not fail, although it should. Here we can use the fact that &lt;tt&gt;TestResponse&lt;/tt&gt; also implements the &lt;tt&gt;filter&lt;/tt&gt; method, which allows us to have &lt;tt&gt;if&lt;/tt&gt; expressions (also known as &lt;em&gt;filters&lt;/em&gt;). The &lt;tt&gt;post&lt;/tt&gt; snippet could then be rewritten like this:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/518452.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;We are again using the Specs matcher to test if the response contains xml and fail otherwise. Notice that this expression does not return true- it need not be boolean. This is due to the fact that &lt;tt&gt;TestResponse&lt;/tt&gt;'s &lt;tt&gt;filter&lt;/tt&gt; method intentionally returns &lt;tt&gt;Unit&lt;/tt&gt;, not &lt;tt&gt;Boolean&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;However, that's too much boilerplate, which we have to do for every time we want to check the contents of an xml response:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Check if the response is valid and has a response code of 200&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Check if the xml is not empty&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Extract the xml&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Only then check the contents of the XML&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;If only we could make &lt;tt&gt;TestResponse&lt;/tt&gt; do what Specs does with XML... But since this is Scala, we can create a wrapper and then transparently substitute it using our implicit conversion:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/518434.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;An important thing to remember about implicit conversions is that if we want them to feel seamless, the wrapper class' methods should return the original class type (the one before the conversion). Otherwise we could get unexpected object classes similarly to what occurred with the Scala 2.7 &lt;tt&gt;RichString&lt;/tt&gt;, for instance with &lt;tt&gt;"aaa" reverse == "aaa"&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Since we have chosen to use the same operator as Specs uses, we had to disambiguate with the &lt;tt&gt;XmlBaseMatchers&lt;/tt&gt; class name, which is the specs trait containing all the XML matching goodness.&lt;br /&gt;&lt;br /&gt;Now we can use our fancy &lt;tt&gt;TestResponse&lt;/tt&gt; operators. Notice that since we return the same class type that we already had, we can chain:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/519605.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;This looks more compact than the original version so you can focus on the API differences and not be distracted by boilerplate preconditions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-689612238461722825?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/689612238461722825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=689612238461722825' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/689612238461722825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/689612238461722825'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2010/08/testing-with-lifts-testframework.html' title='Testing with Lift&apos;s TestFramework'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-4535194480919235595</id><published>2010-03-12T17:14:00.009+02:00</published><updated>2010-03-15T12:07:22.399+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='pomodoro'/><category scheme='http://www.blogger.com/atom/ns#' term='time boxing'/><category scheme='http://www.blogger.com/atom/ns#' term='stress'/><category scheme='http://www.blogger.com/atom/ns#' term='burnout'/><category scheme='http://www.blogger.com/atom/ns#' term='anxiety'/><title type='text'>Pomodoro- what's in it for me?</title><content type='html'>Lately I've been trying to use the &lt;a href="http://en.wikipedia.org/wiki/Pomodoro_Technique"&gt;Pomodoro technique&lt;/a&gt;. I have been using &lt;a href="http://www.davecheong.com/2006/07/26/time-boxing-is-an-effective-getting-things-done-strategy/"&gt;time boxing&lt;/a&gt; for a longer time and find Pomodoro to be a simple and efficient framework which revolves around time boxing.&lt;br /&gt;&lt;br /&gt;Pomodoro being so simple, I was rather surprised to find a &lt;a href="http://www.infoq.com/news/2010/02/pomodoro-critique"&gt;critique&lt;/a&gt; of Pomodoro recently. The critic ignores the fact that the Pomodoro author doesn't mandate that Pomodoro should be used in every occasion; that Pomodoro may use a different time unit than 25 minutes; or that you can void any Pomodoro if you see fit. But let alone the fact that the author misinterprets how strict the Pomodoro should be. By focusing on productivity, it's easy to ignore an equally important aspect- Pomodoro also helps relieve stress and prevents burnout.&lt;br /&gt;&lt;br /&gt;Let me try to explain how Pomodoro achieves this by describing the basic building blocks of the Pomodoro process, which applies to time-boxing in general.&lt;br /&gt;&lt;br /&gt;What is time boxing? Simply put, it's deciding what to do in the next fixed short period of time- and sticking to it. This consists of the following key stages and transitions:&lt;br /&gt;&lt;br /&gt;1) at the start of the Pomodoro- comitting to one thing only for the next time period&lt;br /&gt;&lt;br /&gt;2) during the Pomodoro- trying to focus on this one thing without interruptions&lt;br /&gt;&lt;br /&gt;3) at the end of the Pomodoro- wrapping up and detaching from the work, followed by a short break&lt;br /&gt;&lt;br /&gt;Now let's enumerate some of the reasons for stress, anxiety and burnout. Among these are: multitasking, procrastination, interruptions and obsessing over the completion of a task.&lt;br /&gt;&lt;br /&gt;Comitting to one thing is crucial both for a productive and stress-free state of mind. Multitasking is &lt;a href="http://www.nytimes.com/2007/03/25/business/25multi.html?_r=1"&gt;proven&lt;/a&gt; to lead to anxiety and inefficiency &lt;a href="http://www.time.com/time/magazine/printout/0,8816,1147199,00.html"&gt;time&lt;/a&gt; and &lt;a href="http://www.time.com/time/magazine/article/0,9171,1174696,00.html"&gt;time&lt;/a&gt; &lt;a href="http://arstechnica.com/old/content/2006/03/6417.ars"&gt;again&lt;/a&gt;. Why? First of all, because &lt;a href="http://www.joelonsoftware.com/articles/fog0000000022.html"&gt;switching contexts&lt;/a&gt; is very inefficient and exhausting at that. Getting into the right set of mind to do a task takes time and effort and switching to another task destroys all that mental preparation.&lt;br /&gt;&lt;br /&gt;Multitasking also leads to the impression that we're not acomplishing anything. If you have followed &lt;a href="http://www.joelonsoftware.com/articles/fog0000000022.html"&gt;Joel's article&lt;/a&gt; on the subject, the explanation is simple: if you do 2 tasks which take 10 minutes to finish sequentially, you will have a finished task in 10 minutes. If you switch the tasks every minute, you will only get the first task done after 19 minutes! Multiply this by the number of tasks you're trying to switch every day and you get the picture.&lt;br /&gt;&lt;br /&gt;The conclusion is that multitasking takes more effort and gets things accomplished slower. If this is not frustrating, I don't know what is.&lt;br /&gt;&lt;br /&gt;Furthermore, giving a time limit for a simple task helps you get started. It encourages decomposing the problem into subtasks and transforms a huge amorphous blob of work look like something more palatable. More importantly, getting started is the best way to defeat procrastination, and procrastination is also a major factor for anxiety. Now which is more stressful: a heap of work, where you don't know where to start, or neat organized small tasks, each of which is easier to estimate? Try for yourself.&lt;br /&gt;&lt;br /&gt;Interruptions are another very frequent source of frustration. An extremely important but often forgotten type of interruptions is internal ones. Keeping track of one's desire to chat with someone, check your email or just browse the web for something interesting which has popped in your mind is hard to resist, and can break your flow. It is, however, much easier to control these urges if you know that a break is coming soon, rather than when you feel that it's all work all day long, and a small diversion will just take a couple of seconds. Except that it doesn't.&lt;br /&gt;&lt;br /&gt;Interruptions from other people are harder to avoid, especially in a job, which is related to responding to different events, like answering a support hotline. However, even in the case of phone calls, you cannot be in two unrelated conversations at once. Besides, the criticism of Pomodoro listed two examples which are notably free from interruptions: a surgeon in an operation or a lawyer defending a case in court. You don't need to control task switching in these scenarios because the situation does not allow for any other tasks to be performed. Can you imagine a lawyer in court or an operating surgeon surf the web or check their mail? Thought so.&lt;br /&gt;&lt;br /&gt;Finally, it is very easy to forget that the slow but steady runner wins the race. We often lose track of how much time and effort we have been spending on a task. The short length of the Pomodoro (or any time boxing technique) helps you take a step away and ask: where am I going with this? Is it taking longer than anticipated? Am I actually doing anything or going in circles? Taking a break and detaching yourself from the task at hand helps you see the bigger picture and backtrack if you've reached a dead end. Besides, taking a break will often let your subconscious find a solution, which is otherwise not obvious. Obsessing on completing the task is counterproductive and will leave you unable to take on the next task and burned out in the long run.&lt;br /&gt;&lt;br /&gt;There are other &lt;a href="http://litemind.com/time-boxing/"&gt;benefits&lt;/a&gt; of time-boxing, but all in all, it is a very useful technique. Even people who claim they are able to concentrate without taking breaks, are often doing it subconsciously by letting their minds meander from time to time or switching for a couple of minutes to less stressful aspects of the task. But why rely on being a born time-boxer? Once you agree that time-boxing is helpful, it pays off to make it a habit. It will make you more concentrated and calm.&lt;br /&gt;&lt;br /&gt;And remember- if it ever feels like you're more stressed by using time-boxing, don't push yourself too hard and stop it. Take a break; enjoy your own flow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-4535194480919235595?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/4535194480919235595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=4535194480919235595' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/4535194480919235595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/4535194480919235595'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2010/03/pomodoro-whats-in-it-for-me.html' title='Pomodoro- what&apos;s in it for me?'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-3116386790182585658</id><published>2010-01-17T15:58:00.013+02:00</published><updated>2010-01-26T15:10:24.014+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Is Scala more complicated than what Java tries to become?</title><content type='html'>Is Scala more complicated than Java? My &lt;a href="http://speaking-my-language.blogspot.com/2009/11/is-scala-more-complicated-than-java.html"&gt;last post&lt;/a&gt; did not tell the whole truth. I've only listed Scala features, which have a Java analog. There is a glaring omission of advanced Scala features like implicit conversions, operator overloading, call-by-name parameters and pattern matching. These Scala features are more complicated than what Java has. There, I said it. But then Scala is more complicated in the way a calculator is more complicated than an abacus- sure you can do some of the same stuff with an abacus, but trying to calculate the square root of a number is much more cumbersome.&lt;br /&gt;&lt;br /&gt;However, this complexity pays off, because it lets us simplify many day-to-day features. This post will try a different angle by comparing where Java wants to be and where Scala is right now. I hope after reading it you will at least question your assumptions whether this trade-off is worth it.&lt;br /&gt;&lt;br /&gt;Upon its creation, Java was a fairly simple language. A major reason it took over C++ is because it was specifically designed to steer away from multiple inheritance, automatic memory management and pointer arithmetic. But it's not a simple language anymore, and it's getting more and more complicated.&lt;br /&gt;&lt;br /&gt;Why? Java wasn't designed to be too extensible. Scala, on the other hand, was designed to be &lt;em&gt;scala&lt;/em&gt;ble, in the sense of flexible syntax. The very creators of Java knew very well that a "main goal in designing a language should be to plan for growth" (Guy Steele's famous words from &lt;a href="http://www.brics.dk/~hosc/local/HOSC-12-3-pp221-236.pdf"&gt;Growing a Language&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;We need to expand our definition of language complexity. The language needs to be able to abstract away accidental complexity, or using it will be difficult. Examples of accidental complexity: jumping to a position in your program with goto, and then remembering to go back (before procedural programming); or allocating memory, and then remembering to deallocate it (before garbage collectors). Another example: using a counter to access collections, and remembering to initialize and increment it correctly, not to mention checking when we're done.&lt;br /&gt;&lt;br /&gt;Creating extensions of the language in order to hide these complexities doesn't happen often. When it does, it offers huge rewards. On the other hand, if a language is rigid, even though it looks simple, this forces you to invent your own arcane workarounds. When the language leaves you to deal with complexity on your own, the resulting code will necessarily be complicated.&lt;br /&gt;&lt;br /&gt;Let's see what special new language features Java tries to add to the language, which Scala can do because of its flexibility and extensibility.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Pattern matching&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Pattern matching is often compared with Java's switch/case statement. I have listed pattern matching as something which doesn't have an analog in Java, because comparing it to "switch" really doesn't do it justice. Pattern matching can be used for arbitrary types, it can be used to assign variables and check preconditions; the compiler will check if the match is exhaustive and if the &lt;a href="http://speaking-my-language.blogspot.com/2009/11/error-detection-with-pattern-matching.html"&gt;types make sense&lt;/a&gt;. Meanwhile Java has only recently accepted &lt;a href="http://blogs.sun.com/darcy/entry/project_coin_strings_in_switch"&gt;Strings in switch statements&lt;/a&gt;, which is only scratching the surface of Scala's pattern matching.&lt;br /&gt;&lt;br /&gt;Furthermore, Scala is using pattern matching all through the language- from variable assignment to exception handling. To compare, the proposal for handling &lt;a href="http://bugs.sun.com/view_bug.do?bug_id=4432337"&gt;multiple exceptions&lt;/a&gt; in Java is postponed yet again.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Case classes&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;In order to get rid of Java's verbose getters, setters, hashCode and equals, one solution is to muck with the javac compiler, like the folks from &lt;a href="http://java.dzone.com/interview-lombok"&gt;Project Lombok&lt;/a&gt; have done. Is going to the guts of javac complicated? I'm sure it is.&lt;br /&gt;&lt;br /&gt;In Scala, you can do it if you just define your classes as case classes.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Implicit conversions&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;In short, implicit conversions help transparently convert one type to another if the original type doesn't support the operations requested.&lt;br /&gt;&lt;br /&gt;There are many examples where this is useful.&lt;br /&gt;&lt;br /&gt;What in Java is hardcoded in the language as conversions and promotions, in Scala is defined using implicit conversions. This is another example where Java can get quite complicated. In most cases where you need to decide how to convert a method argument, for instance, you must have in mind narrowing and widening conversions, promotions, autoboxing, varargs and overriding (whew!). In Scala, the advantage of having implicit conversions is that you can inspect the code, where no ambiguity can result. You can analyze the conversions taking place in the interpreter by supplying the "-Xprint:typer" parameter. You can even disable these implicits, if you don't like them, by shadowing the import.&lt;br /&gt;&lt;br /&gt;Another example of what implicits can do is adding methods and functionality to existing classes. Dynamic languages already do that easily using open classes and "missing method" handlers. In Java one way to do this using bytecode manipulation trickery via libraries like cglib, bcel, asm or javassist.&lt;br /&gt;&lt;br /&gt;Bytecode manipulation in Java is required for popular libraries like Hibernate, Spring and AspectJ. Few "enterprise" Java developers can imagine development without Hibernate and Spring. Although there are many more things you can do with AspectJ, it can be used to emulate implicits with &lt;a href="http://www.eclipse.org/aspectj/doc/released/progguide/semantics-declare.html#inter-type-member-declarations"&gt;type member declarations&lt;/a&gt;. However, even though using AspectJ is a more high-level way to solve the problem, it adds even more complexity, as it defines additional keywords and constructs.&lt;br /&gt;&lt;br /&gt;If you're new to Scala, you don't lose much if you don't know how implicit conversions work, just like you don't need to know about the magic that happens behind the scenes when Hibernate persists objects or when Spring creates its proxies. Just as with bytecode generation, you're not advised to use this feature often, as it is difficult to use. Still, you'll be glad it exists, because someone will create a library which will make your life and the life of many developers so much easier.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Operator overloading&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;The line between operators and methods in Scala is blurred- you can use the symbols +, -, /, *, etc. as method names. In fact, that's exactly how arithmetic operators work in Scala- they are method invocations (relax, everything is optimized by the compiler).&lt;br /&gt;&lt;br /&gt;Some people object that operator overloading adds unnecessary complexity, because they can be abused. Still, you can also abuse &lt;a href="http://freeworld.thc.org/root/phun/unmaintain.html"&gt;method naming&lt;/a&gt; in much the same way. For instance, some hapless folk can define methods with visually similar symbols, like &lt;em&gt;method1&lt;/em&gt;, &lt;em&gt;methodl&lt;/em&gt; and &lt;em&gt;methodI&lt;/em&gt;. They can use inconsistent capitalization, like &lt;em&gt;addJar&lt;/em&gt; or &lt;em&gt;addJAR&lt;/em&gt;. One could use meaningless identifiers like &lt;em&gt;ahgsl&lt;/em&gt;. Why should operator best practices be different than method naming best practices?&lt;br /&gt;&lt;br /&gt;What &lt;em&gt;is&lt;/em&gt; complicated is treating numeric types like &lt;em&gt;int&lt;/em&gt;s and &lt;em&gt;BigInteger&lt;/em&gt; differently. Not only that, but operations with &lt;em&gt;BigInteger&lt;/em&gt; are very verbose and barely readable even with simple expressions. To compare, this is how a recursive definition of factorial looks like in Scala with BigInteger:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def factorial (x: BigInt): BigInt =&lt;br /&gt;  if (x == 0) 1 else x * factorial(x - 1)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is how it would look if Scala &lt;a href="http://www.slideshare.net/Odersky/fosdem-2009-1013261"&gt;didn't support&lt;/a&gt; operator overloading:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def factorial (x: BigInteger): BigInteger =&lt;br /&gt;  if (x == BigInteger.ZERO)&lt;br /&gt;    BigInteger.ONE&lt;br /&gt;  else&lt;br /&gt;    x.multiply(factorial(x.subtract(BigInteger.ONE)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Call by name&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;One of the proposals for Java 7 language extension was &lt;a href="http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000011.html"&gt;automatic resource management&lt;/a&gt;. This is one more rule to the language, which you need to remember. Without this feature, code is also unnecessarily complicated, because it forces you to remember to always close resources after using them- if you slip up, subtle bugs with leaking files or connections can result.&lt;br /&gt;&lt;br /&gt;In Scala, it's easy to add &lt;a href="http://jim-mcbeath.blogspot.com/2008/09/creating-control-constructs-in-scala.html"&gt;language constructs like this&lt;/a&gt;. Using function blocks, which are evaluated only when they are invoked, one can emulate almost &lt;a href="http://daily-scala.blogspot.com/2009/11/defining-custom-control-structures.html"&gt;any language construct&lt;/a&gt;, including while, if, etc..&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Existential types&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Existential types are roughly an alternative to Java wildcards, only &lt;a href="http://www.drmaciver.com/2008/01/minor-revelation-about-scala-existential-types/"&gt;more powerful&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Martin Odersky: If Java had reified types and no raw types or wildcards, I don't think we would have that much use for existential types and I doubt they would be in Scala.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;If Martin Odersky says that existential types &lt;a href="http://www.artima.com/scalazine/articles/scalas_type_system.html"&gt;wouldn't be in the language&lt;/a&gt; if it wasn't for Java compatibility, why would you even need to know about them? Mostly if you need to interoperate with Java generics.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Scala tries to define fewer language rules, which are however more universal. Many of these advanced features are not often used, but they pay off by allowing to create constructs, which in Java would require specific hardcoded additions to the language. In Scala, they can be defined simply as libraries.&lt;br /&gt;&lt;br /&gt;Why does it matter that it's in the libraries, and not hardcoded in the language? You can more easily evolve and adapt these features, you can add your own extensions, and you can even disable some of the library parts or replace them.&lt;br /&gt;&lt;br /&gt;The conclusion is that if a language is not designed to be extended, it will eventually develop features, which are not well-integrated and this language will collapse under the weight of its own complexity.&lt;br /&gt;&lt;br /&gt;Finally, learning something so that you avoid a lot of routine error-prone operations reduces effort by increasing the level of abstraction, at the cost of additional complexity. When you were in school, it was complicated to learn multiplication, but if you got over it, it would save you from quite a bit of repetition than if you just used addition.&lt;br /&gt;&lt;br /&gt;P.S. I realize it's not possible to resolve the issue once and for all which language is more complicated- Java or Scala- in a post or two. First of all, have in mind that &lt;a href="http://bradapp.blogspot.com/2006/05/simple-aint-easy-myths-and.html"&gt;simple is not the same as easy to use&lt;/a&gt;. There are also many topics which are open for discussion. I haven't touched on Scala traits; I haven't mentioned functions as first-class constructs compared to the Java 7 closure proposal; and there's a lot that can be said about how Scala obviates many Java design patterns. Extending the Scala syntax via compiler plugins is another interesting advanced topic.&lt;br /&gt;&lt;br /&gt;I suppose someone could even write a blog post about these topics some day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-3116386790182585658?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/3116386790182585658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=3116386790182585658' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/3116386790182585658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/3116386790182585658'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2010/01/is-scala-more-complicated-than-what.html' title='Is Scala more complicated than what Java tries to become?'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-5122588130106558242</id><published>2010-01-04T20:46:00.001+02:00</published><updated>2010-01-05T10:19:12.931+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Is Scala more complicated than Java?</title><content type='html'>One &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=268561"&gt;Scala-related thread&lt;/a&gt; on Artima drew a lot of attention: "Is Scala really more complicated than Java?". This post really struck a nerve. Whoever claims that Scala is much more complicated than Java has clearly not seen a Java Programmer Certification in a while and is probably not using many new features since Java 5 came out.&lt;br /&gt;&lt;br /&gt;What I'll try to prove in this post is not that Scala is &lt;em&gt;not&lt;/em&gt; a complicated language. There are certainly many languages which are simpler. The core features which are used reasonably often are indeed a simplification over Java. Scala also has features which are more complicated than what Java has. However, the complicated Scala features are more specialized at extending the language while the complexity of Java is usually imposed on everyone including the beginner.&lt;br /&gt;&lt;br /&gt;This post will also not try to describe the language features in exhaustive detail- that's what the language specification tries to achieve, and the blog post is already long enough. I will assume that you know about the core language rules or can easily look them up.&lt;br /&gt;&lt;br /&gt;What is complexity? Many conflate it with unreadability, some say it's the opposite to &lt;em&gt;ease of use&lt;/em&gt;. Let's start with the following definition of complexity: it's the many special exceptions (pun not intended) to the rules, making the whole system difficult to understand and remember.&lt;br /&gt;&lt;br /&gt;Based on that definition, let's run a comparison of language features of Java and Scala.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Keywords&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Java has &lt;a href="http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html"&gt;more reserved words&lt;/a&gt; than Scala. Even when we remove the words of primitive types (&lt;tt&gt;boolean&lt;/tt&gt;, &lt;tt&gt;int&lt;/tt&gt;, &lt;tt&gt;float&lt;/tt&gt;, etc.) Scala still has &lt;a href="http://programming-scala.labs.oreilly.com/ch02.html#reserved-words-table"&gt;less keywords&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Scala misses some of Java's control structures&lt;/li&gt; Yes, &lt;tt&gt;continue&lt;/tt&gt; and &lt;tt&gt;break&lt;/tt&gt; (well, at least until Scala 2.8) are not part of the language, as they are not deemed a best-practice way to solve programming problems.&lt;br /&gt; &lt;li&gt;if/then/else&lt;/li&gt; in Scala returns a value, thus eliminating the need for the only ternary operator in Java, "?:", the use of which has long been discouraged.&lt;br /&gt; &lt;li&gt;for loop&lt;/li&gt; Java folks discovered late in the game that the enhanced for loop is much less complicated to use in cases when you don't need the counter index. And they were right- it's one more detail which you (or at least newbies) can get wrong. But why stop there- Scala has a much more universal &lt;tt&gt;for&lt;/tt&gt; loop, and there aren't two different syntaxes as in Java.&lt;br /&gt; &lt;li&gt;Scala keywords not in Java&lt;/li&gt; one might argue that the &lt;tt&gt;override&lt;/tt&gt; keyword in Scala complicates things as you might do the same thing in Java with an &lt;tt&gt;@Override&lt;/tt&gt; annotation. That's not quite the case, as you still might override a method by accident and forget to put the annotation (as it's not mandatory), and then the compiler will not give as much as a warning! So that's one more special case you need to worry about and keep in your head. When you start using traits, you definitely start to appreciate that &lt;tt&gt;override&lt;/tt&gt; is a keyword.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Access modifiers&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Java has four access modifiers: default (package), &lt;tt&gt;private&lt;/tt&gt;, &lt;tt&gt;public&lt;/tt&gt; and &lt;tt&gt;protected&lt;/tt&gt;. Scala has three, but it can combine them with a scope for protection. This flexibility allows you to define access control, for which Java has no analogs. They are also readable because they look self explanatory. For instance, if you have the class &lt;tt&gt;org.apache.esme.actor.UserActor&lt;/tt&gt;, these are the Scala equivalents for Java's access modifiers:&lt;br /&gt;&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;&lt;dt&gt;private[actor]&lt;/dt&gt; &lt;dd&gt;Same as package access in Java&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;private[UserActor]&lt;/dt&gt; &lt;dd&gt;Same as &lt;tt&gt;private&lt;/tt&gt; in Java&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;Scala's default access is public (yay, one less keyword!).&lt;br /&gt;&lt;br /&gt;On the other hand, by defining the scope, Scala allows visibility types, which Java doesn't have:&lt;br /&gt;&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;&lt;dt&gt;private[this]&lt;/dt&gt; &lt;dd&gt;the member is accessible only from this instance. Not even other instances from the same class can access it&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;private[esme]&lt;/dt&gt; &lt;dd&gt;access for a package and subpackages. How many times did you have to use clumsy workarounds in Java because subpackages couldn't access the parent package?&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;protected&lt;/dt&gt; &lt;dd&gt;only subclasses can access the field. This is more consistent than Java's &lt;tt&gt;protected&lt;/tt&gt; keyword. In Java, you have to remember that both subclasses &lt;em&gt;and&lt;/em&gt; classes in the same package can access the field. How's that for remembering arbitrary rules?&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;private&lt;/dt&gt; &lt;dd&gt;This will not allow you to access inner objects. This is also more consistent than Java's &lt;tt&gt;private&lt;/tt&gt; access, which is perhaps indicative of the fact that inner objects in Java were bolted on after the first version of the language was created&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Namespaces&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Java has four namespaces (fields, methods, packages, types), Scala has two (one for types, one for everything else). This has important implications when overriding. In Scala, you can start with a parameterless &lt;tt&gt;def&lt;/tt&gt; (method definition) and then override with a &lt;tt&gt;val&lt;/tt&gt; (immutable variable). This helps enforce the uniform access principle: whether you access a field or a method, this doesn't restrict you later on, because the syntax is the same everywhere you access it.&lt;br /&gt;&lt;br /&gt;One thing which you cannot do is define a variable and a method with the same method. The "Programming in Scala" book explicitly mentions that allowing this would be a code smell because of possible code duplication and the ambiguity which could arise.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Types and the type system&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Scala's type system has been criticized for being too complex, but let's have a look at Java's type system.&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;Primitive types&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;There are many exceptions in Java's type system, which make the language hard to use and evolve. Java has primitive types, while in Scala everything is an object, making this valid code: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(1 to 3) foreach println&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Java's primitive types make a lot of things harder- before Java 5, manual wrapping in collections, e.g. &lt;tt&gt;int&lt;/tt&gt; in &lt;tt&gt;Integer&lt;/tt&gt;, &lt;tt&gt;boolean&lt;/tt&gt; in &lt;tt&gt;Boolean&lt;/tt&gt;, etc. was a pain. After auto-boxing and unboxing came out, the syntax is cleaner, but the overhead remains, as well as some very subtle bugs. For example, auto-unboxing a null wrapper type will cause a &lt;tt&gt;NullPointerException&lt;/tt&gt;.&lt;br /&gt;&lt;br /&gt;There is a lot of code duplication because of primitive types- you always have to specify special cases and can't be truly generic.&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;Generics&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;Scala has generics &lt;a href="http://www.codecommit.com/blog/java/interop-between-java-and-scala"&gt;done right&lt;/a&gt;. For instance, you can define covariance at the declaration site, whereas Java requires you to do this at the call site. This, combined with Scala's type inference allows one to use generified libraries without having to know or define the complete type signature.&lt;br /&gt;&lt;br /&gt;Java has yet another "special" type: arrays. As a result the rules for the underlying array type and the generified &lt;tt&gt;ArrayList&lt;/tt&gt; are quite different and inconsistent. The type of arrays is checked at runtime, while the genericity of &lt;tt&gt;ArrayList&lt;/tt&gt; is checked at compile-time. As a result, inappropriate assignment to an array element results in a &lt;a href="http://safalra.com/programming/java/wrong-type-erasure/"&gt;&lt;tt&gt;ArrayStoreException&lt;/tt&gt;&lt;/a&gt; only at runtime.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Constructors&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Java initialization order in object construction is a pain to get right. The puzzlers on the certification exam use the most bizarre mix of static and instance initializer blocks and constructors calling or inheriting other constructors.&lt;br /&gt;&lt;br /&gt;In Scala, any code which isn't part of a method or member variable declaration is executed as the primary constructor. You can define auxiliary constructors which call either the primary one or another auxiliary one defined in the same class before it. Can you come up with anything simpler?&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Uniform syntax&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Scala is sometimes accused of using too many symbols. Whatever you've seen, it's mostly not part of the language, but of the libraries. You can override them and even disable them. What does Java have to say about special symbols?&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;Arrays&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;Arrays in Java are accessed via square brackets. In Scala, parentheses are used, because accessing an array index is a method call (called apply). Don't worry though, the compiler optimizes this away.&lt;br /&gt;&lt;br /&gt;&lt;h5&gt;Collection literals&lt;/h5&gt;&lt;br /&gt;&lt;br /&gt;Java has a lot of special syntax for array instantiation and will soon have ones for instantiating lists, sets and maps. Scala, again, creates these special collections using factory methods in the companion objects: &lt;tt&gt;Array(1,2,3)&lt;/tt&gt;, &lt;tt&gt;List(1,2,3)&lt;/tt&gt;, &lt;tt&gt;Map((1,2))&lt;/tt&gt;. Lists can also be created using the cons "operator", but here's the trick: it's not actually an operator. It's a &lt;a href="http://www.scala-lang.org/docu/files/api/scala/List.html#%3A%3A(B)"&gt;method&lt;/a&gt;, appending to the list. You can also create a map using the arrow tuple syntax: &lt;tt&gt;Map(1-&gt;2)&lt;/tt&gt;. And again, this is not "special" syntax, which is part of the language- it's a &lt;a href="http://www.scala-lang.org/docu/files/api/scala/Predef$object.ArrowAssoc.html#-%3E(B)"&gt;method&lt;/a&gt;, constructing a tuple!&lt;br /&gt;&lt;br /&gt;Now someone might smirk and think: "Ha, gotcha! Do you mean to say that simply because you've pushed the complexity out of the language and into the libraries you don't need to deal with it?". True, but let's have a look at Java and its ever growing standard libraries. It has AWT &lt;em&gt;and&lt;/em&gt; Swing. It has old I/O and new I/O (gosh, which one do I use?). It has RMI (do you remember RMI?) and OMG, it even has CORBA. These libraries will never die. Methods in &lt;tt&gt;Thread&lt;/tt&gt; have been deprecated for ages. There's also no sign that the ill-conceived &lt;tt&gt;Date&lt;/tt&gt;/&lt;tt&gt;Calendar&lt;/tt&gt; classes will ever be removed, but you still must know JodaTime if you hope to get any job with dates done.&lt;br /&gt;&lt;br /&gt;More importantly, extending the language easily helps abstract away the details and evolve the language without creating tons of special cases. As per our definition, special cases add up to increase complexity. We'll explore the topic of extending the language in the followup post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-5122588130106558242?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/5122588130106558242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=5122588130106558242' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/5122588130106558242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/5122588130106558242'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/11/is-scala-more-complicated-than-java.html' title='Is Scala more complicated than Java?'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-7026518078543917492</id><published>2009-12-28T00:24:00.005+02:00</published><updated>2010-01-04T11:39:54.269+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphs'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><title type='text'>Bridge-crossing with Clojure</title><content type='html'>Solving puzzles has become popular among colleagues at the end of this year. One of these was the popular &lt;a href="http://en.wikipedia.org/wiki/Bridge_and_torch_problem"&gt;Bridge and torch problem&lt;/a&gt;. To summarize: four men have to cross a bridge in the dark with a torch, which can only light the way for two persons. These guys can cross the bridge in 1, 2, 5 and 10 minutes, respectively. When two people cross the bridge, it takes the time needed for the slower one to pass.&lt;br /&gt;&lt;br /&gt;I'm not going to explain the optimal solution, but I wanted to show how this is a graph-traversal problem, which is amenable to solving using &lt;a href="http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm"&gt;Dijkstra's algorithm&lt;/a&gt;. I also noticed that some clever guy has &lt;a href="http://www.aswinvanwoudenberg.com/index.php/2009/07/03/bridge-and-torch-puzzle/"&gt;solved the puzzle&lt;/a&gt; using Prolog. So an idea was formed: generate the tree of solutions using a language, which I'm not really comfortable with (so I can practice and learn it better). I settled on Clojure, because I wanted to learn it this year (and the year is almost over).&lt;br /&gt;&lt;br /&gt;The solution has a lot to do with sets. The state of each of the banks (which I'll call &lt;em&gt;left&lt;/em&gt; and &lt;em&gt;right&lt;/em&gt;) is a set of people, which are identified by their crossing speed. If we generate the list of possible combinations between the persons for each next move and recurse into them, then we'll have the tree of all solutions. In order to avoid indefinitely long (and stupid) solutions, we assume that going forward always takes two men, and going back takes only one.&lt;br /&gt;&lt;br /&gt;The necessary libraries are &lt;em&gt;set&lt;/em&gt;, &lt;em&gt;combinatorics&lt;/em&gt; and &lt;em&gt;str-utils&lt;/em&gt;. That's where I start:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;use &lt;span class="hl sym"&gt;'[&lt;/span&gt;clojure.contrib.combinatorics&lt;span class="hl sym"&gt;])&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;use &lt;span class="hl sym"&gt;'[&lt;/span&gt;clojure.&lt;span class="hl kwf"&gt;set&lt;/span&gt;&lt;span class="hl sym"&gt;])&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;use &lt;span class="hl sym"&gt;'[&lt;/span&gt;clojure.contrib.str-utils&lt;span class="hl sym"&gt;])&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;use &lt;span class="hl sym"&gt;'[&lt;/span&gt;clojure.contrib.pprint&lt;span class="hl sym"&gt;])&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here are the initial data structures: the two river banks are sets, the right one is empty:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;def&lt;/span&gt; left #&lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl num"&gt;2&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl num"&gt;5&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl num"&gt;10&lt;/span&gt;&lt;span class="hl sym"&gt;})&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;def&lt;/span&gt; right #&lt;span class="hl sym"&gt;{})&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And here's a first version of the solution:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;defn&lt;/span&gt; forward &lt;span class="hl sym"&gt;[&lt;/span&gt;left right steps minutes&lt;span class="hl sym"&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;map&lt;/span&gt; #&lt;span class="hl sym"&gt;(&lt;/span&gt;back&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;difference&lt;/span&gt; left %&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;union&lt;/span&gt; right &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;set&lt;/span&gt; %&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;cons&lt;/span&gt; % steps&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(+&lt;/span&gt; minutes &lt;span class="hl sym"&gt;(&lt;/span&gt;reduce &lt;span class="hl kwf"&gt;max&lt;/span&gt; %&lt;span class="hl sym"&gt;)) )&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl sym"&gt;(&lt;/span&gt;combinations left &lt;span class="hl num"&gt;2&lt;/span&gt;&lt;span class="hl sym"&gt;)) )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;defn&lt;/span&gt; back &lt;span class="hl sym"&gt;[&lt;/span&gt;left right steps minutes&lt;span class="hl sym"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;empty? left&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;list&lt;/span&gt; steps minutes&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;map&lt;/span&gt; #&lt;span class="hl sym"&gt;(&lt;/span&gt;forward&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;union&lt;/span&gt; left &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;set&lt;/span&gt; %&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;difference&lt;/span&gt; right %&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;cons&lt;/span&gt; % steps&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(+&lt;/span&gt; minutes &lt;span class="hl sym"&gt;(&lt;/span&gt;reduce &lt;span class="hl kwf"&gt;max&lt;/span&gt; %&lt;span class="hl sym"&gt;)) )&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl sym"&gt;(&lt;/span&gt;combinations right &lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;)) ) )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;pprint &lt;span class="hl sym"&gt;(&lt;/span&gt;forward left right nil &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This prints some semblance of a tree, constructed by nested lists (hey, that's what Lisp is good for, remember?). What I didn't like about this is that there is too much repetition. There are many parts of these functions, which look the same. In order to evolve the solution, I wanted to extract the common parts in a single function:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;defn&lt;/span&gt; solve &lt;span class="hl sym"&gt;[&lt;/span&gt;from to steps minutes group&lt;span class="hl sym"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;and&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;empty? to&lt;span class="hl sym"&gt;) (&lt;/span&gt;&lt;span class="hl kwf"&gt;not&lt;/span&gt; group&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;list&lt;/span&gt; steps minutes&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;mapcat&lt;/span&gt; #&lt;span class="hl sym"&gt;(&lt;/span&gt;solve&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;union&lt;/span&gt; to &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;set&lt;/span&gt; %&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;difference&lt;/span&gt; from %&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;cons&lt;/span&gt; % steps&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(+&lt;/span&gt; minutes &lt;span class="hl sym"&gt;(&lt;/span&gt;reduce &lt;span class="hl kwf"&gt;max&lt;/span&gt; %&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;not&lt;/span&gt; group&lt;span class="hl sym"&gt;) )&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl sym"&gt;(&lt;/span&gt;combinations from &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; group &lt;span class="hl num"&gt;2 1&lt;/span&gt;&lt;span class="hl sym"&gt;))) ) )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;pprint &lt;span class="hl sym"&gt;(&lt;/span&gt;solve left right nil &lt;span class="hl num"&gt;0&lt;/span&gt; true&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The function behaves differently depending on whether the group of people crossing consists of two or just one person. Also, the tree is now flattened, so the optimal solution can be easily found like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(print (reduce #(if (&lt; (second %1) (second %2)) %1 %2) (apply hash-map (solve left right nil 0 true))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next step, I want to be able to collect a lot more data about each state, so I need to stop messing around with lists of lists and use something more organized like a hashmap. There's a reason Clojure includes the function &lt;em&gt;second&lt;/em&gt;, but not &lt;em&gt;third&lt;/em&gt; or, heaven forbid, &lt;em&gt;fourth&lt;/em&gt;. Naming each part of your ad-hoc data structure plays a major role in readability.&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;defn&lt;/span&gt; solve &lt;span class="hl sym"&gt;[&lt;/span&gt;from to steps minutes group&lt;span class="hl sym"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;and&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;empty? to&lt;span class="hl sym"&gt;) (&lt;/span&gt;&lt;span class="hl kwf"&gt;not&lt;/span&gt; group&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;{:&lt;/span&gt;steps steps&lt;span class="hl sym"&gt;, :&lt;/span&gt;from from&lt;span class="hl sym"&gt;, :&lt;/span&gt;&lt;span class="hl kwf"&gt;time&lt;/span&gt; minutes&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;{:&lt;/span&gt;steps steps&lt;span class="hl sym"&gt;, :&lt;/span&gt;from from&lt;span class="hl sym"&gt;, :&lt;/span&gt;&lt;span class="hl kwf"&gt;time&lt;/span&gt; minutes&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl sym"&gt;:&lt;/span&gt;solutions &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;map&lt;/span&gt; #&lt;span class="hl sym"&gt;(&lt;/span&gt;solve&lt;br /&gt;                    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;union&lt;/span&gt; to &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;set&lt;/span&gt; %&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;                    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;difference&lt;/span&gt; from %&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;cons&lt;/span&gt; % steps&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                    &lt;span class="hl sym"&gt;(+&lt;/span&gt; minutes &lt;span class="hl sym"&gt;(&lt;/span&gt;reduce &lt;span class="hl kwf"&gt;max&lt;/span&gt; %&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;                    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;not&lt;/span&gt; group&lt;span class="hl sym"&gt;) )&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;combinations from &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; group &lt;span class="hl num"&gt;2 1&lt;/span&gt;&lt;span class="hl sym"&gt;)))} ) )&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now the interesting part can begin- rendering the tree in a nice graphical form using &lt;a href="http://www.graphviz.org/"&gt;GraphViz&lt;/a&gt;. Watch this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;defn&lt;/span&gt; printgraph &lt;span class="hl sym"&gt;[&lt;/span&gt;solution_tree&lt;span class="hl sym"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;let&lt;/span&gt; &lt;span class="hl sym"&gt;[&lt;/span&gt;steps &lt;span class="hl sym"&gt;(&lt;/span&gt;solution_tree &lt;span class="hl sym"&gt;:&lt;/span&gt;steps&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;        nodename &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;nil? steps&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;root&amp;quot;&lt;/span&gt; steps&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;        from &lt;span class="hl sym"&gt;(&lt;/span&gt;solution_tree &lt;span class="hl sym"&gt;:&lt;/span&gt;from&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;        label &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(= (&lt;/span&gt;&lt;span class="hl kwf"&gt;count&lt;/span&gt; from&lt;span class="hl sym"&gt;) (&lt;/span&gt;&lt;span class="hl kwf"&gt;count&lt;/span&gt; left&lt;span class="hl sym"&gt;)) (&lt;/span&gt;solution_tree &lt;span class="hl sym"&gt;:&lt;/span&gt;&lt;span class="hl kwf"&gt;time&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt; from&lt;span class="hl sym"&gt;)]&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;str&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt; nodename &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt; &lt;span class="hl str"&gt;[label=&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt; label &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;];&lt;/span&gt;&lt;span class="hl esc"&gt;\n&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;contains? &lt;span class="hl sym"&gt;:&lt;/span&gt;solutions solution_tree&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;str-join &lt;span class="hl str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;                    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;map&lt;/span&gt; #&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;str&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt; nodename &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt; &lt;span class="hl str"&gt;-&amp;gt; &amp;quot;&lt;/span&gt;&lt;br /&gt;                            &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt; &lt;span class="hl sym"&gt;(:&lt;/span&gt;steps %&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;                            &lt;span class="hl str"&gt;&amp;quot; [label=&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;intersection&lt;/span&gt; from &lt;span class="hl sym"&gt;(:&lt;/span&gt;from %&lt;span class="hl sym"&gt;))&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;];&lt;/span&gt;&lt;span class="hl esc"&gt;\n&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;                            &lt;span class="hl sym"&gt;(&lt;/span&gt;printgraph %&lt;span class="hl sym"&gt;))&lt;/span&gt;&lt;br /&gt;                        &lt;span class="hl sym"&gt;(&lt;/span&gt;solution_tree &lt;span class="hl sym"&gt;:&lt;/span&gt;solutions&lt;span class="hl sym"&gt;)) ) ) ) ) )&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And now you can output the recursive stuff wrapped with the header and footer like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;println&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;digraph G {&amp;quot;&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;print&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;printgraph &lt;span class="hl sym"&gt;(&lt;/span&gt;solve left right nil &lt;span class="hl num"&gt;0&lt;/span&gt; true&lt;span class="hl sym"&gt;)))&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;println&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This graph shows each node as the state of alternating river banks, and the edges show the people crossing the bridge. The leaves display the number of minutes which it took for this particular combination of crossings.&lt;br /&gt;&lt;br /&gt;I also wanted to generate a mind map for FreeMind, but since it doesn't support edge labels, I used the persons crossing for the nodes:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;defn&lt;/span&gt; mindmap &lt;span class="hl sym"&gt;[&lt;/span&gt;solution_tree&lt;span class="hl sym"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;(&lt;/span&gt;str-join &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\n&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;map&lt;/span&gt; #&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;str&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl str"&gt;&amp;quot;&amp;lt;node text=&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;intersection&lt;/span&gt; &lt;span class="hl sym"&gt;(:&lt;/span&gt;from solution_tree&lt;span class="hl sym"&gt;) (:&lt;/span&gt;from %&lt;span class="hl sym"&gt;))&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;(&lt;/span&gt;mindmap %&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl str"&gt;&amp;quot;&amp;lt;/node&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl sym"&gt;(&lt;/span&gt;solution_tree &lt;span class="hl sym"&gt;:&lt;/span&gt;solutions&lt;span class="hl sym"&gt;)) ) )&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now generating the complete file according to the FreeMind format:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;println&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;&amp;lt;map&amp;gt;&amp;lt;node text=&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;root&lt;/span&gt;&lt;span class="hl esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="hl str"&gt;&amp;gt;&lt;/span&gt;&lt;span class="hl esc"&gt;\n&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;print&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;mindmap &lt;span class="hl sym"&gt;(&lt;/span&gt;solve left right nil &lt;span class="hl num"&gt;0&lt;/span&gt; true&lt;span class="hl sym"&gt;)))&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;println&lt;/span&gt; &lt;span class="hl str"&gt;&amp;quot;&amp;lt;/node&amp;gt;&amp;lt;/map&amp;gt;&lt;/span&gt;&lt;span class="hl esc"&gt;\n&lt;/span&gt;&lt;span class="hl str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally, finding the optimal solution is just a wee bit more involved, because it requires traversing the tree recursively, but that's no problem for us anymore:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;defn&lt;/span&gt; optimal &lt;span class="hl sym"&gt;[&lt;/span&gt;tree&lt;span class="hl sym"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;contains? tree &lt;span class="hl sym"&gt;:&lt;/span&gt;solutions&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;reduce #&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(&amp;lt; (&lt;/span&gt;&lt;span class="hl kwd"&gt;second&lt;/span&gt; %&lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;) (&lt;/span&gt;&lt;span class="hl kwd"&gt;second&lt;/span&gt; %&lt;span class="hl num"&gt;2&lt;/span&gt;&lt;span class="hl sym"&gt;))&lt;/span&gt; %&lt;span class="hl num"&gt;1&lt;/span&gt; %&lt;span class="hl num"&gt;2&lt;/span&gt;&lt;span class="hl sym"&gt;) (&lt;/span&gt;&lt;span class="hl kwd"&gt;map&lt;/span&gt; optimal &lt;span class="hl sym"&gt;(&lt;/span&gt;tree &lt;span class="hl sym"&gt;:&lt;/span&gt;solutions&lt;span class="hl sym"&gt;)))&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;list&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;tree &lt;span class="hl sym"&gt;:&lt;/span&gt;steps&lt;span class="hl sym"&gt;) (&lt;/span&gt;tree &lt;span class="hl sym"&gt;:&lt;/span&gt;&lt;span class="hl kwf"&gt;time&lt;/span&gt;&lt;span class="hl sym"&gt;)) ) )&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwf"&gt;print&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;optimal &lt;span class="hl sym"&gt;(&lt;/span&gt;solve left right nil &lt;span class="hl num"&gt;0&lt;/span&gt; true&lt;span class="hl sym"&gt;)))&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In conclusion, I knew that one can write very compact code in Clojure (and any Lisp, in general), and this was certainly true here. I didn't use the Clojure-specific concurrency primitives or the lazy sequences, so my example would probably look similar in another Lisp. I did try to make it as functional as possible and Clojure does encourage that.&lt;br /&gt;&lt;br /&gt;Some of the difficulties I had could be solved by static type checking, but I guess I'm spoiled by Scala. I've ran into small problems like renaming a variable and forgetting to rename (or misspelling) some instance of it in my code. I also tend to mix up which of the arguments to &lt;em&gt;contains?&lt;/em&gt; comes first, and which second. This is probably because you can exchange a symbol as a key in a hashmap, and the hashmap without changing the meaning, e.g. (:from solution_tree) and (solution_tree :from). Of course, this is a problem with dynamic typing, not of Clojure in particular (and could probably be interpreted as a problem of using the language inappropriately).&lt;br /&gt;&lt;br /&gt;Whatever the small hurdles, the problem was solved. Having fun? Check. Generating nice graphs &lt;em&gt;and&lt;/em&gt; mind maps to impress colleagues? Check. Learning a bit of Lispy Clojure in the process? Check. Mission accomplished.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-7026518078543917492?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/7026518078543917492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=7026518078543917492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7026518078543917492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7026518078543917492'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/12/bridge-crossing-with-clojure.html' title='Bridge-crossing with Clojure'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-5751163694107587520</id><published>2009-12-03T22:58:00.003+02:00</published><updated>2009-12-04T10:43:49.634+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interpolation'/><category scheme='http://www.blogger.com/atom/ns#' term='implicit conversions'/><category scheme='http://www.blogger.com/atom/ns#' term='reflection'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>String interpolation in Scala</title><content type='html'>When I tried Scala for the first time, one of the first missing language features I noticed was string interpolation (you guessed it, I was using Ruby at the time). Of course, this is a small convenience rather than a major language feature and usually String.format and java.util.Formatter are pretty good substitutes. Still, string interpolation comes &lt;a href="http://old.nabble.com/Why-Martin-hates-string-interpolation-(Was:-Re:-Formatting-Questions-Summary)-td23774178.html"&gt;now and then&lt;/a&gt; in Scala discussions and one has to wonder if Scala's powerful language extension facilities can emulate a feature like this.&lt;br /&gt;&lt;br /&gt;It turns out you can get reasonably close:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="kwa"&gt;trait&lt;/span&gt; InterpolationContext &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;class&lt;/span&gt; InterpolatedString&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; s&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt;&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;def&lt;/span&gt; i &lt;span class="sym"&gt;=&lt;/span&gt; interpolate&lt;span class="sym"&gt;(&lt;/span&gt;s&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  implicit &lt;span class="kwa"&gt;def&lt;/span&gt; str2interp&lt;span class="sym"&gt;(&lt;/span&gt;s&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt;&lt;span class="sym"&gt;) =&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; InterpolatedString&lt;span class="sym"&gt;(&lt;/span&gt;s&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; interpolate&lt;span class="sym"&gt;(&lt;/span&gt;s&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt;&lt;span class="sym"&gt;) = {&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;val&lt;/span&gt; sb &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;StringBuilder&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;var&lt;/span&gt; prev &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="num"&gt;0&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;for&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;m &lt;span class="sym"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="esc"&gt;\\&lt;/span&gt;&lt;span class="str"&gt;$&lt;/span&gt;&lt;span class="esc"&gt;\\&lt;/span&gt;&lt;span class="str"&gt;{.+?&lt;/span&gt;&lt;span class="esc"&gt;\\&lt;/span&gt;&lt;span class="str"&gt;}&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;r&lt;span class="sym"&gt;.&lt;/span&gt;findAllIn&lt;span class="sym"&gt;(&lt;/span&gt;s&lt;span class="sym"&gt;).&lt;/span&gt;matchData&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;      sb&lt;span class="sym"&gt;.&lt;/span&gt;append&lt;span class="sym"&gt;(&lt;/span&gt;s&lt;span class="sym"&gt;.&lt;/span&gt;substring&lt;span class="sym"&gt;(&lt;/span&gt;prev&lt;span class="sym"&gt;,&lt;/span&gt; m&lt;span class="sym"&gt;.&lt;/span&gt;start&lt;span class="sym"&gt;))&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwa"&gt;val&lt;/span&gt; matchString &lt;span class="sym"&gt;=&lt;/span&gt; m&lt;span class="sym"&gt;.&lt;/span&gt;matched&lt;br /&gt;      &lt;span class="kwa"&gt;var&lt;/span&gt; identifier &lt;span class="sym"&gt;=&lt;/span&gt; matchString&lt;span class="sym"&gt;.&lt;/span&gt;substring&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; matchString&lt;span class="sym"&gt;.&lt;/span&gt;length &lt;span class="sym"&gt;-&lt;/span&gt; &lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwa"&gt;try&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;val&lt;/span&gt; method &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;this&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;getClass&lt;span class="sym"&gt;.&lt;/span&gt;getMethod&lt;span class="sym"&gt;(&lt;/span&gt;identifier&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;        sb&lt;span class="sym"&gt;.&lt;/span&gt;append&lt;span class="sym"&gt;(&lt;/span&gt;method&lt;span class="sym"&gt;.&lt;/span&gt;invoke&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;this&lt;/span&gt;&lt;span class="sym"&gt;))&lt;/span&gt;&lt;br /&gt;      &lt;span class="sym"&gt;}&lt;/span&gt; &lt;span class="kwa"&gt;catch&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;case&lt;/span&gt; _&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;NoSuchMethodException&lt;/span&gt; &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt;&lt;br /&gt;        sb&lt;span class="sym"&gt;.&lt;/span&gt;append&lt;span class="sym"&gt;(&lt;/span&gt;matchString&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;      prev &lt;span class="sym"&gt;=&lt;/span&gt; m&lt;span class="sym"&gt;.&lt;/span&gt;end&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;    sb&lt;span class="sym"&gt;.&lt;/span&gt;append&lt;span class="sym"&gt;(&lt;/span&gt;s&lt;span class="sym"&gt;.&lt;/span&gt;substring&lt;span class="sym"&gt;(&lt;/span&gt;prev&lt;span class="sym"&gt;,&lt;/span&gt; s&lt;span class="sym"&gt;.&lt;/span&gt;length&lt;span class="sym"&gt;))&lt;/span&gt;&lt;br /&gt;    sb&lt;span class="sym"&gt;.&lt;/span&gt;toString&lt;br /&gt;  &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;object&lt;/span&gt; Test &lt;span class="kwa"&gt;extends&lt;/span&gt; InterpolationContext &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;val&lt;/span&gt; a &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; main&lt;span class="sym"&gt;(&lt;/span&gt;args&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;Array&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="kwc"&gt;String&lt;/span&gt;&lt;span class="sym"&gt;]) {&lt;/span&gt;&lt;br /&gt;    println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;expanded: ${a}; not expanded: ${b}; more text&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;i&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;How does this work? If you call the &lt;em&gt;i&lt;/em&gt; method on a String, it will force implicit conversion to a InterpolatedString, similar to how the &lt;em&gt;r&lt;/em&gt; method works for converting to a Regex. The &lt;em&gt;interpolate&lt;/em&gt; method uses reflection to find a method with the name equal to the identifier delimited by "${" and "}". This works both for vals and defs due to Scala's adhering to the uniform access principle. If the delimited string is not a valid identifier or a parameterless method with this name doesn't exist, it is not substituted, but stays as it is.&lt;br /&gt;&lt;br /&gt;How do you use it? Just extend or mix in the InterpolationContext trait in the class where you want this to work, and then call &lt;em&gt;i&lt;/em&gt; on the Strings where you want interpolation to work. The InterpolationContext trait serves two purposes- first of all, it imports the implicit conversion to the interpolated string, and second it provides access to the methods of the current object via reflection.&lt;br /&gt;&lt;br /&gt;The limitations of this method are that interpolation only works on member vals and defs of the current object only. I rather like this, because you know you can't accidentally construct a String from user input in an html form like "Name: ${System.exec(\"echo echo pwned &gt;&gt; .bashrc\")}". Also, interpolation doesn't work for private members as well as local variables. Finally, you have to both mix in or extend the trait and call a method on every String (even though it's a one-letter method). This is not too bad, because you can control the scope where interpolation works and therefore avoid and debug nasty surprises easier.&lt;br /&gt;&lt;br /&gt;I don't see this as a pattern, which can be used in real-life projects, and I don't see the use of implicits here worthy of emulation. Nevertheless, trying to copy features from other languages is instructive about the limitations of your current language of choice and the tradeoffs you get for these features. Last but not least- even if it's a gimmick feature, implementing it was fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-5751163694107587520?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/5751163694107587520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=5751163694107587520' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/5751163694107587520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/5751163694107587520'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/12/string-interpolation-in-scala.html' title='String interpolation in Scala'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-7891258830985304286</id><published>2009-11-23T22:36:00.005+02:00</published><updated>2009-11-25T10:08:34.721+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pattern matching'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Error detection with pattern matching</title><content type='html'>Scala's pattern matching is one of the most powerful features in the language. It not only helps write concise and very readable code, but also helps prevent trivial errors.&lt;br /&gt;&lt;br /&gt;Let's say you want to save a line or two of code when comparing for some empty data structure like a List. You decide to use comparison for equality:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; items &lt;span class="sym"&gt;=&lt;/span&gt; Nil&lt;br /&gt;&lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;items &lt;span class="sym"&gt;==&lt;/span&gt; Nil&lt;span class="sym"&gt;)&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;No items&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then you decide to refactor and turn the items collection into a Set. The Scala compiler is clever and should give you a warning, right? Well, not quite:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; items &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;Set&lt;/span&gt;&lt;span class="sym"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;items &lt;span class="sym"&gt;==&lt;/span&gt; Nil&lt;span class="sym"&gt;)&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;No items&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This results in nothing printed, as the expression evaluates to false. Of course, given the types it's perfectly clear at compile-time that this will never be true. Can't the compiler give you a hint? Indeed, it will if you use pattern matching:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;items match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; Nil &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;No items&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; _ &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will result in the following error message:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;error: pattern type is incompatible with expected type;&lt;br /&gt; found   : object Nil&lt;br /&gt; required: scala.collection.immutable.Set[Nothing]&lt;br /&gt;         case Nil =&gt; println("No items")&lt;br /&gt;              ^&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The examples are contrived (unparameterized Nil and Set?), but you get the point. Yes, Nil can never be a value of the Set type. You might think this is fairly obvious, but pattern matching can be a life saver when implicit conversions are involved. Consider this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="str"&gt;&amp;quot;heh&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;reverse &lt;span class="sym"&gt;==&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;heh&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What does this evaluate to? This should be obvious, right? But the value is false! If you used pattern matching, you would easily see why:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="str"&gt;&amp;quot;heh&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;reverse match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;heh&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;obvious?&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will make the compiler very nervous, and this is the reason why:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;error: type mismatch;&lt;br /&gt; found   : java.lang.String("heh")&lt;br /&gt; required: scala.runtime.RichString&lt;br /&gt;         case "heh" =&gt; "obvious?"&lt;br /&gt;              ^&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So reverse converts the String to the wrapper RichString, which is not the same type as String.&lt;br /&gt;&lt;br /&gt;I have had similar problems detecting a bug where I was checking for equality with None a variable which was of type &lt;a href="http://scala-tools.org/mvnsites-snapshots/liftweb/lift-common/scaladocs/net/liftweb/common/Box.html"&gt;net.liftweb.common.Box&lt;/a&gt; (a type very similar conceptually to Scala's built-in Option).&lt;br /&gt;&lt;br /&gt;This made me adopt a general rule to prefer pattern matching rather than equality comparison. The bugs it catches are sometimes subtle and hard to see, and that's exactly what Scala's rich static type checker tries to avoid. Use it to your advantage.&lt;br /&gt;&lt;br /&gt;Since we're talking about bugs caught by pattern matching, there's one subtle bug, which is often (though not always) caught by the compiler (another contrived example follows):&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; items &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;Set&lt;/span&gt;&lt;span class="sym"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="kwc"&gt;Set&lt;/span&gt;&lt;span class="sym"&gt;()&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; items &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;empty&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; _ &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;full&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will result in an error, which looks a little bit unusual to the newbie:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;error: unreachable code&lt;br /&gt;         case _ =&gt; println("full")&lt;br /&gt;                   ^&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This error is usually crying out loud: hey, you're inadvertently using &lt;a href="http://speaking-my-language.blogspot.com/2009/02/3-scala-gotchas.html"&gt;variable binding&lt;/a&gt; instead of constant matching! The newly bound variable &lt;em&gt;items&lt;/em&gt; shadows the existing variable with the same name and all other cases after it will never match.&lt;br /&gt;&lt;br /&gt;One way to fix it is to use backticks to prevent the name to be bound to a new variable:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;Set&lt;/span&gt;&lt;span class="sym"&gt;()&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; `items` &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;empty&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; _ &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;full&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As a rule of thumb it is advised to use CapitalLetters for case classes and constants which you intend to pattern match.&lt;br /&gt;&lt;br /&gt;This error wouldn't have occurred if you used equality comparison in the first place, but even in mildly complex cases pattern matching trumps plain equality checking in readability and detecting errors. Apparently, there are cases where pattern matching fails (for instance, matching structural types), so there's still no reason to deprecate good old "==". But there are many more errors, which pattern matching catches, like checking if the match is exhaustive. So there's no point in saving a couple of characters but lose the type safety you expect from Scala.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-7891258830985304286?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/7891258830985304286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=7891258830985304286' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7891258830985304286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7891258830985304286'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/11/error-detection-with-pattern-matching.html' title='Error detection with pattern matching'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-395821818333532473</id><published>2009-11-04T23:04:00.004+02:00</published><updated>2009-11-05T00:06:02.594+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interpreter'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Embedded Scala interpreter</title><content type='html'>The Scala interpreter is proof that a statically typed language can have features most people only expect from a dynamically-typed language. One of the cool uses of an interpreter is embedding it within your application. This allows you to conveniently experiment with Scala and probably even interact with object instances in your running system. I won't explain how the interpreter works here, but I will try to show you a simple way of embedding the interpreter.&lt;br /&gt;&lt;br /&gt;As it usually happens, someone &lt;a href="http://suereth.blogspot.com/2009/04/embedding-scala-interpreter.html"&gt;beat me to it&lt;/a&gt;. Josh Suereth explains in great detail how to embed an interpreter, but he has done so many customizations that his solution would probably fit on several pages.&lt;br /&gt;&lt;br /&gt;I wanted a simpler solution which one could understand at a glance. The code for &lt;a href="http://lotrepls.appspot.com/"&gt;Lord of the REPLs&lt;/a&gt; is &lt;a href="http://code.google.com/p/lotrepls/source/browse/trunk/src/com/google/lotrepls/server/interpreters/ScalaInterpreter.java"&gt;much shorter&lt;/a&gt; although it doesn't customize much of what the standard interpreter offers.&lt;br /&gt;&lt;br /&gt;I tried to come up with the shortest working version you could possibly get away with. Provided I create the settings properly, this is what I could muster:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; out &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; java&lt;span class="sym"&gt;.&lt;/span&gt;io&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;StringWriter&lt;/span&gt;&lt;span class="sym"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; interpreter &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; scala&lt;span class="sym"&gt;.&lt;/span&gt;tools&lt;span class="sym"&gt;.&lt;/span&gt;nsc&lt;span class="sym"&gt;.&lt;/span&gt;Interpreter&lt;span class="sym"&gt;(&lt;/span&gt;settings&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;PrintWriter&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;out&lt;span class="sym"&gt;))&lt;/span&gt;&lt;br /&gt;interpreter&lt;span class="sym"&gt;.&lt;/span&gt;interpret&lt;span class="sym"&gt;(&lt;/span&gt;code&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Not too much code, is it? (Half of it is probably due to the full package names). Now you could collect your output from the "out" stream and probably convert to String if you need using "out.toString".&lt;br /&gt;&lt;br /&gt;Not so fast, though. I said this works if I have the appropriate settings:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; settings &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; scala&lt;span class="sym"&gt;.&lt;/span&gt;tools&lt;span class="sym"&gt;.&lt;/span&gt;nsc&lt;span class="sym"&gt;.&lt;/span&gt;Settings&lt;span class="sym"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem here is that the interpreter doesn't find two of the crucial jars needed for its proper functioning: scala-compiler.jar and scala-library.jar. When it doesn't it spits out the following error:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;scala.tools.nsc.FatalError: object scala not found.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Thanks to the &lt;a href="http://groups.google.com/group/maven-and-scala/browse_thread/thread/3373e69e357c595c"&gt;following discussion&lt;/a&gt; by Eric Torreborre (author of &lt;a href="http://etorreborre.blogspot.com/"&gt;Specs&lt;/a&gt;) I managed to find out that one needs to add to the bootclasspath of the settings object:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; origBootclasspath &lt;span class="sym"&gt;=&lt;/span&gt; settings&lt;span class="sym"&gt;.&lt;/span&gt;bootclasspath&lt;span class="sym"&gt;.&lt;/span&gt;value&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; pathList &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;jarPathOfClass&lt;span class="sym"&gt;(&lt;/span&gt;compilerPath&lt;span class="sym"&gt;),&lt;/span&gt;&lt;br /&gt;                         jarPathOfClass&lt;span class="sym"&gt;(&lt;/span&gt;libPath&lt;span class="sym"&gt;))&lt;/span&gt;&lt;br /&gt;settings&lt;span class="sym"&gt;.&lt;/span&gt;bootclasspath&lt;span class="sym"&gt;.&lt;/span&gt;value &lt;span class="sym"&gt;= (&lt;/span&gt;origBootclasspath &lt;span class="sym"&gt;::&lt;/span&gt; pathList&lt;span class="sym"&gt;).&lt;/span&gt;mkString&lt;span class="sym"&gt;(&lt;/span&gt;java&lt;span class="sym"&gt;.&lt;/span&gt;io&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;File&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;separator&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One could hardcode the path to these two jars, but that's not too flexible. If we want to do it right, we might create a function which discovers the path to the jar from the name of a class that's in it:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; jarPathOfClass&lt;span class="sym"&gt;(&lt;/span&gt;className&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt;&lt;span class="sym"&gt;) = {&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwc"&gt;Class&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;forName&lt;span class="sym"&gt;(&lt;/span&gt;className&lt;span class="sym"&gt;).&lt;/span&gt;getProtectionDomain&lt;span class="sym"&gt;.&lt;/span&gt;getCodeSource&lt;span class="sym"&gt;.&lt;/span&gt;getLocation&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now you could find the paths to these jars like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; compilerPath &lt;span class="sym"&gt;=&lt;/span&gt; jarPathOfClass&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;scala.tools.nsc.Interpreter&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; libPath &lt;span class="sym"&gt;=&lt;/span&gt; jarPathOfClass&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;scala.ScalaObject&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I've read that getProtectionDomain.getCodeSource returns null in some classloaders and might have problems specifically with OSGi. In that case, one might need to resort to the following hack:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; jarPathOfClass&lt;span class="sym"&gt;(&lt;/span&gt;className&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt;&lt;span class="sym"&gt;) = {&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;val&lt;/span&gt; resource &lt;span class="sym"&gt;=&lt;/span&gt; className&lt;span class="sym"&gt;.&lt;/span&gt;split&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'.'&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;mkString&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;.class&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;val&lt;/span&gt; path &lt;span class="sym"&gt;=&lt;/span&gt; getClass&lt;span class="sym"&gt;.&lt;/span&gt;getResource&lt;span class="sym"&gt;(&lt;/span&gt;resource&lt;span class="sym"&gt;).&lt;/span&gt;getPath&lt;br /&gt;  &lt;span class="kwa"&gt;val&lt;/span&gt; indexOfFile &lt;span class="sym"&gt;=&lt;/span&gt; path&lt;span class="sym"&gt;.&lt;/span&gt;indexOf&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;file:&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;val&lt;/span&gt; indexOfSeparator &lt;span class="sym"&gt;=&lt;/span&gt; path&lt;span class="sym"&gt;.&lt;/span&gt;lastIndexOf&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'!'&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  path&lt;span class="sym"&gt;.&lt;/span&gt;substring&lt;span class="sym"&gt;(&lt;/span&gt;indexOfFile&lt;span class="sym"&gt;,&lt;/span&gt; indexOfSeparator&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With the last ugly piece of code creating an interpreter is not so concise anymore, but sometimes you can't be both robust and concise.&lt;br /&gt;&lt;br /&gt;If you want to see the above snippets assembled in one piece you can check out Apache ESME's source code for the &lt;a href="http://svn.apache.org/repos/asf/incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/ScalaInterpreter.scala"&gt;ScalaInterpreter action&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Warning: interpreting code directly in your application is a huge security risk and might not always be a good idea.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-395821818333532473?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/395821818333532473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=395821818333532473' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/395821818333532473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/395821818333532473'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/11/embedded-scala-interpreter.html' title='Embedded Scala interpreter'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-7342243694608742038</id><published>2009-10-13T12:07:00.008+03:00</published><updated>2009-10-14T22:49:37.971+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mocks'/><category scheme='http://www.blogger.com/atom/ns#' term='implicit conversions'/><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scala closures as poor man's mocks</title><content type='html'>Groovy has this feature that you can use a closure whenever you need an interface with one method only. A class implementing the interface is automatically created, and the closure provides the implementation of this single method. This process is called closure coercion and is particularly convenient to &lt;a href="http://docs.codehaus.org/display/GROOVY/Developer+Testing+using+Closures+instead+of+Mocks"&gt;make tests readable and concise&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm not yet sure about the relative advantages of such code everywhere, since there might be ambiguities or the intent might be obscured. Tests usually contain a lot of boilerplate, though, so I'm all for making them more concise. Except for readability, people would be more likely to write a test if it doesn't take much effort to create yet another trivial mock.&lt;br /&gt;&lt;br /&gt;Who tests your tests though? You don't need to answer. Still, the page about &lt;a href="http://docs.codehaus.org/display/GROOVY/Groovy+way+to+implement+interfaces"&gt;implementing interfaces in Groovy&lt;/a&gt; warns of this trap: "Be careful that you don't accidentally define the map with { }". Type safety could help sometimes when writing tests. Or at least that's a very good excuse to try to emulate this Groovy feature in Scala.&lt;br /&gt;&lt;br /&gt;In Scala there are implicit conversions, which help define a controlled way to coerce a value to a different type. We cannot automatically convert all closures to all possible single-method interfaces in scope, but we can choose several we are using especially often (as it happens in tests). For instance, if we want to use a mock of java.lang.Readable often enough, we could define the following implicit conversion:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;import&lt;/span&gt; java&lt;span class="sym"&gt;.&lt;/span&gt;nio&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;CharBuffer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;implicit &lt;span class="kwa"&gt;def&lt;/span&gt; fun2readable&lt;span class="sym"&gt;(&lt;/span&gt;f&lt;span class="sym"&gt;:&lt;/span&gt; Function1&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="kwc"&gt;CharBuffer&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt;Int&lt;span class="sym"&gt;]):&lt;/span&gt; &lt;span class="kwc"&gt;Readable&lt;/span&gt; &lt;span class="sym"&gt;=&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Readable&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt; &lt;span class="kwa"&gt;def&lt;/span&gt; read&lt;span class="sym"&gt;(&lt;/span&gt;cb&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;CharBuffer&lt;/span&gt;&lt;span class="sym"&gt;) =&lt;/span&gt; f&lt;span class="sym"&gt;(&lt;/span&gt;cb&lt;span class="sym"&gt;) }&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now everywhere we need a Readable, we might just drop in the appropriate closure instead (technically, this is not a mock, but a &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;stub&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; readable&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;Readable&lt;/span&gt; &lt;span class="sym"&gt;= {&lt;/span&gt;cb&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;CharBuffer&lt;/span&gt; &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; cb&lt;span class="sym"&gt;.&lt;/span&gt;put&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;12 34&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt; &lt;span class="num"&gt;5&lt;/span&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; s &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; java&lt;span class="sym"&gt;.&lt;/span&gt;util&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;Scanner&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;readable&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;assert &lt;span class="sym"&gt;(&lt;/span&gt;s&lt;span class="sym"&gt;.&lt;/span&gt;nextInt &lt;span class="sym"&gt;==&lt;/span&gt; &lt;span class="num"&gt;12&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Compare this with the Groovy version:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def readable = { it.put("12 34"); 5 } as Readable&lt;br /&gt;def s = new Scanner(readable)&lt;br /&gt;assert s.nextInt() == 12&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the Scala version, we are explicitly defining the type of the variable in order to force the implicit conversion. In methods, where Readable is expected as an argument, explicitly naming the type will not be necessary, whereas in Groovy you always need to coerce using "as Readable":&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; s &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; java&lt;span class="sym"&gt;.&lt;/span&gt;util&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;Scanner&lt;/span&gt;&lt;span class="sym"&gt;({&lt;/span&gt;cb&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;CharBuffer&lt;/span&gt; &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; cb&lt;span class="sym"&gt;.&lt;/span&gt;put&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;12 34&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt; &lt;span class="num"&gt;5&lt;/span&gt;&lt;span class="sym"&gt;})&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So in Scala you're trading some verbosity up front for some conciseness in all of the code where the implicit conversion is visible. Furthermore, the type checker guarantees that only closures with the correct signature are converted to the interface in question (i.e. with an input of CharBuffer and output of Int) and will flag a compile-time error otherwise.&lt;br /&gt;&lt;br /&gt;The reader might be tempted to also emulate &lt;a href="http://docs.codehaus.org/display/GROOVY/Groovy+Mocks#GroovyMocks-MockingusingMapcoercion"&gt;map coercion&lt;/a&gt;, but beware of an unexpected difficulty: it's not easy to define both a closure (with one argument) and map coercion. Since a Map in scala &lt;a href="http://psnively.github.com/2009/10/03/if-it-quacks-like-a-function.html"&gt;is a function&lt;/a&gt; and due to type erasure, the compiler won't know whether to substitute the Map or the Function!&lt;br /&gt;&lt;br /&gt;Can you generate these implicits automatically without defining them? Maybe with a Scala &lt;a href="http://www.scala-lang.org/node/140"&gt;compiler plugin&lt;/a&gt;, but then you lose some of the transparency of knowing which implicits you've defined.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-7342243694608742038?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/7342243694608742038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=7342243694608742038' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7342243694608742038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7342243694608742038'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/10/scala-closures-as-poor-mans-mocks.html' title='Scala closures as poor man&apos;s mocks'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-2161563883278235258</id><published>2009-09-26T16:05:00.003+03:00</published><updated>2009-09-28T11:12:32.571+03:00</updated><title type='text'>Scala interpreter in Firefox' location bar</title><content type='html'>&lt;a href="http://SimplyScala.com"&gt;SimplyScala&lt;/a&gt; is awesome for trying out some quick Scala tricks. However, you can go one step further, and execute Scala one-liners in your Firefox location bar!&lt;br /&gt;&lt;br /&gt;1. Create a bookmark to URL http://www.simplyscala.com/interp?code=%s&lt;br /&gt;2. Associate a keyword to the bookmark. Mine is "scala", you can try something shorter like "s" or "&gt;".&lt;br /&gt;3. Now when you type "scala &amp;lt;expression&amp;gt;", the expression will be sent to SimlpyScala and evaluated. For instance, "scala List(1,2,3).reverse"&lt;br /&gt;&lt;br /&gt;Why does this work? Whenever you have a keyword associated with a bookmark Firefox expands "%s" in the URL to the text following the keyword. Check this &lt;a href="http://lifehacker.com/196779/hack-attack-firefox-and-the-art-of-keyword-bookmarking"&gt;Lifehacker article&lt;/a&gt; for details.&lt;br /&gt;&lt;br /&gt;The nice thing is that your bindings are kept in your session, so you can use variable names defined in previous invocations. There are inconveniences, for instance you cannot easily preview your history and it's hard to review inputs which are more than a couple of lines long.&lt;br /&gt;&lt;br /&gt;I also find that in combination with URL-shortening services it's an acceptable alternative to using code snippet sharing sites like gist.github.com or paste.pocoo.org. The code is actually part of the URL, which makes sense for shorter code snippets. You don't have syntax highlighting, but you have the evaluated result readily available.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-2161563883278235258?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/2161563883278235258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=2161563883278235258' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/2161563883278235258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/2161563883278235258'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/09/scala-interpreter-in-firefox-location.html' title='Scala interpreter in Firefox&apos; location bar'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-2971150297775221443</id><published>2009-09-16T23:27:00.007+03:00</published><updated>2009-09-17T12:29:17.648+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='multiple assignment'/><category scheme='http://www.blogger.com/atom/ns#' term='extractors'/><category scheme='http://www.blogger.com/atom/ns#' term='pattern matching'/><category scheme='http://www.blogger.com/atom/ns#' term='structural types'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>3 things you didn't know Scala pattern matching can(not) do</title><content type='html'>Since I started learning Scala, pattern matching has become a favorite feature. But powerful as it is, pattern matching has some limitations. On the other hand, there are some unexpected ways to use pattern matching.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt; Fake multiple assignment of tuples &lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;You already knew you can initialize multiple variables using the &lt;a href="http://pragmaticdesign.blogspot.com/2009/04/scala-multiple-assignment.html"&gt;tuple syntax&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;a&lt;span class="sym"&gt;,&lt;/span&gt; b&lt;span class="sym"&gt;) = (&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I want to do the same with closure parameters, though. For example, to swap the elements of 2-tuples in a list:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; &lt;span class="sym"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; map &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  t &lt;span class="sym"&gt;=&amp;gt; (&lt;/span&gt;t&lt;span class="sym"&gt;.&lt;/span&gt;_2&lt;span class="sym"&gt;,&lt;/span&gt; t&lt;span class="sym"&gt;.&lt;/span&gt;_1&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Still, using numbered slots for tuples doesn't seem as readable. It would be great if we could easily assign variables with meaningful names to document the purpose of the elements of the tuple. Parameters are already packed in a tuple, so why can't I do this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; &lt;span class="sym"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; map &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;val&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;num&lt;span class="sym"&gt;,&lt;/span&gt; str&lt;span class="sym"&gt;) =&lt;/span&gt; _&lt;span class="sym"&gt;; (&lt;/span&gt;str&lt;span class="sym"&gt;,&lt;/span&gt; num&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately this is not legal syntax. Of course, I can explicitly bind the tuple to a temporary variable and then decompose it:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; &lt;span class="sym"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; map &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  t &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kwa"&gt;val&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;num&lt;span class="sym"&gt;,&lt;/span&gt; str&lt;span class="sym"&gt;) =&lt;/span&gt; t&lt;span class="sym"&gt;; (&lt;/span&gt;str&lt;span class="sym"&gt;,&lt;/span&gt; num&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But this seems too verbose for Scala. Fortunately, there's a trick which can help. Pattern matches are actually instances of partial functions! The closures used for map, filter, etc. are functions, too. This means we can use a pattern match to &lt;a href="http://la.scala.la/post/115219644/more-detuplings"&gt;bind variables&lt;/a&gt; to the closure parameters:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; &lt;span class="sym"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; map &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;num&lt;span class="sym"&gt;,&lt;/span&gt; str&lt;span class="sym"&gt;) =&amp;gt; (&lt;/span&gt;str&lt;span class="sym"&gt;,&lt;/span&gt; num&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt; Match the last element of a list &lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Decomposing lists in pattern matching is another power feature of Scala. You can match the first element of a list:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;3&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; &lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; _&lt;span class="sym"&gt;*) =&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;yeah!&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The underscore-star (_*) symbol serves as a placeholder for the rest of the elements of the list. You can also do this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;3&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; &lt;span class="num"&gt;1&lt;/span&gt; &lt;span class="sym"&gt;::&lt;/span&gt; _ &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;hurray!&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Which mimicks construction of the list using the cons operator. So what if I want to match on the last element instead of the first?&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; to &lt;span class="num"&gt;9&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;toList match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; &lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;_&lt;span class="sym"&gt;*,&lt;/span&gt; &lt;span class="num"&gt;8&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;9&lt;/span&gt;&lt;span class="sym"&gt;) =&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;sure&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hey, this seems like it's working! Not so fast, though:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; to &lt;span class="num"&gt;9&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;toList match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; &lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;_&lt;span class="sym"&gt;*,&lt;/span&gt; &lt;span class="num"&gt;18&lt;/span&gt;&lt;span class="sym"&gt;) =&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;yeah, right&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In fact, in Scala 2.8 this syntax will trigger an error message: "_* may only come last"&lt;br /&gt;&lt;br /&gt;How about using the alternative notation?&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; to &lt;span class="num"&gt;9&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;toList match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; _ &lt;span class="sym"&gt;::&lt;/span&gt; &lt;span class="num"&gt;9&lt;/span&gt; &lt;span class="sym"&gt;::&lt;/span&gt; Nil&lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;no way&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately Scala expects the placeholder to be an element, not a list. The triple colon expects a list, will it work?&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; to &lt;span class="num"&gt;9&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;toList match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; _ &lt;span class="sym"&gt;:::&lt;/span&gt; &lt;span class="num"&gt;9&lt;/span&gt; &lt;span class="sym"&gt;::&lt;/span&gt; Nil &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;absolutely not&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Nope, this isn't even recognized by the compiler. While you're wondering why there is a ::: operator, but it's unknown to Scala in pattern matching, remember that ::, which is used in pattern matching, is actually a class. Furthermore, the syntax "a :: b" is in fact a more readable expression of "::(a, b)", which in turn is a short form of "call unapply on the matching expression and check if it decomposes to a and b".&lt;br /&gt;&lt;br /&gt;And this, in short, is how the Scala black magic, called "extractors", works. But can we also use it to match on the last element of a list? Sure! Just define an object (let's call it "::&gt;") and define its unapply method. The method expects a list and must return a tuple of the "init" part of the list and the "last".&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;object&lt;/span&gt; &lt;span class="sym"&gt;::&amp;gt; {&lt;/span&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; unapply&lt;span class="sym"&gt;[&lt;/span&gt;A&lt;span class="sym"&gt;] (&lt;/span&gt;l&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;A&lt;span class="sym"&gt;]) =&lt;/span&gt; Some&lt;span class="sym"&gt;( (&lt;/span&gt;l&lt;span class="sym"&gt;.&lt;/span&gt;init&lt;span class="sym"&gt;,&lt;/span&gt; l&lt;span class="sym"&gt;.&lt;/span&gt;last&lt;span class="sym"&gt;) )}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;3&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; _ &lt;span class="sym"&gt;::&amp;gt;&lt;/span&gt; last &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;last&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; to &lt;span class="num"&gt;9&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;toList match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; &lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;3&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;4&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;5&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;6&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;7&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;8&lt;/span&gt;&lt;span class="sym"&gt;) ::&amp;gt;&lt;/span&gt; &lt;span class="num"&gt;9&lt;/span&gt; &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;woah!&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt; to &lt;span class="num"&gt;9&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;toList match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; &lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;3&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;4&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;5&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;6&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;7&lt;/span&gt;&lt;span class="sym"&gt;) ::&amp;gt;&lt;/span&gt; &lt;span class="num"&gt;8&lt;/span&gt; &lt;span class="sym"&gt;::&amp;gt;&lt;/span&gt; &lt;span class="num"&gt;9&lt;/span&gt; &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;w00t!&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt; Match structural types &lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;Since you've heard of structural types, didn't you wish you could do this to find out whether a class has a certain method?&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; t&lt;span class="sym"&gt;: {&lt;/span&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; length&lt;span class="sym"&gt;:&lt;/span&gt; Int&lt;span class="sym"&gt;} =&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;cool!&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, here again we are fooled in thinking method checking happens when matching the class. It's not:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; t&lt;span class="sym"&gt;: {&lt;/span&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; aoeu&lt;span class="sym"&gt;:&lt;/span&gt; Int&lt;span class="sym"&gt;} =&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;really?&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The reason for this is that the class type is erased to AnyRef. Unfortunately, there's no clean workaround for this- yet. This looks positively ugly:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;List&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; t&lt;span class="sym"&gt;: {&lt;/span&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; aoeu&lt;span class="sym"&gt;:&lt;/span&gt; Int&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;          &lt;span class="kwa"&gt;if&lt;/span&gt; t&lt;span class="sym"&gt;.&lt;/span&gt;getClass&lt;span class="sym"&gt;.&lt;/span&gt;getMethods&lt;span class="sym"&gt;.&lt;/span&gt;exists&lt;span class="sym"&gt;{&lt;/span&gt;_&lt;span class="sym"&gt;.&lt;/span&gt;getName &lt;span class="sym"&gt;==&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;aoeu&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;} =&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;not really!&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Do not despair, though- there's a chance that this feature is going to land in Scala &lt;a href="http://pragmaticdesign.blogspot.com/2009/07/unchecked-scala-ducktyping.html"&gt;sooner or later&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-2971150297775221443?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/2971150297775221443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=2971150297775221443' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/2971150297775221443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/2971150297775221443'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/09/3-things-you-didnt-know-scala-pattern.html' title='3 things you didn&apos;t know Scala pattern matching can(not) do'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-1104255048100053535</id><published>2009-06-23T16:33:00.002+03:00</published><updated>2009-06-23T17:19:39.433+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='feeds'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>The ultimate Twitter client</title><content type='html'>...is a Feed reader!&lt;br /&gt;&lt;br /&gt;OK, not quite, but after some thinking about the top features the ideal Twitter client should have, I found feed readers have most. For the minor drawback of not being able to post messages, you get:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Marking messages as read&lt;/li&gt;&lt;br /&gt;Marking mails as read is absolutely critical for email clients, since you can easily see at any time which messages are new. There's enough cognitive load on your brain already, it doesn't need to rescan again and again messages you've already seen. Paradoxically, many Twitter clients don't have this feature, and there are far more messages in a typical twitter timeline than in a typical email inbox.&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Fixed replies&lt;/li&gt;&lt;br /&gt;If you know what #fixreplies means, you know that some folks prefer to see the replies of their friends to people who are not also their friends. This is an excellent way to discover new people to follow and manages to capture a lot more interesting conversations. Well, if you track the individual feeds of your friends (more on that later), all of their replies are there.&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Favorites of friends&lt;/li&gt;&lt;br /&gt;Yeah, most Twitter clients let you see your own favorites, but that's backwards. Of course, you already know which tweets you've marked as favorites! What you really want to know is what &lt;span style="font-style:italic;"&gt;others&lt;/span&gt;, mostly your &lt;span style="font-style:italic;"&gt;friends&lt;/span&gt; have marked as favorites. You could see favorites' timelines of individual users, but who would want to check all of their friends' favorites manually? There's a real need to track an aggregated list of messages your friends &lt;span style="font-style:italic;"&gt;recommend&lt;/span&gt;. The whole flood of retweet (aka "RT") messages are a response to this need. Retweeting is not a solution though, as it pollutes Twitter and especially search results with tweets with duplicate content. Ever searched for Scala on the day The Register published the article that Twitter is "dumping" Ruby for Scala (ignore the fact Twitter was not really dumping Ruby)?&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Tracking&lt;/li&gt;&lt;br /&gt;Remember the days of old when Twitter had Instant Messaging integration? And you could track messages from any user by a keyword? It couldn't scale, of course. Then there was Twitterspy, which provided identical functionality, but it fell down under the weight of popularity too. Well, you can use Twitter search. And you can create an atom feed out of your Twitter search. It does not have the real-time responsiveness of IM, but I'd take that over nothing.&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;No follow/unfollow counting&lt;/li&gt;&lt;br /&gt;This is actually a feature. People have complained before that followers' count should go, since it serves no purpose other than trophy collecting and is no measure of the usefulness of someone's tweets.&lt;br /&gt;&lt;br /&gt;There's also Qwitter. It's a service, which shows you when someone quits, and the message after they quit. If you thought for a moment this is good, think again. Rarely ever someone decides you're not worth following after a single tweet. The corresponding reaction could be either to become too careful about what you tweet (you become too boring) or demanding an explanation from the qwitter (lame, but I heard some are doing it). Noone will chastise me if I unsubscribe from their blog because I have no time to read it, why take Twitter personally?&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;But some of these "features" require you to import the feed of every single one of your users. Noone in their right mind would do that manually, but there's a way to generate a list of feeds in the form of an OPML file (which many readers can import). First of all, get a &lt;a href="http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-friends%C2%A0ids"&gt;list of your friends&lt;/a&gt;. Then apply the following XSL stylesheet:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;xsl:stylesheet version=&amp;quot;1.0&amp;quot;&lt;br /&gt; xmlns:xsl=&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;xsl:output method=&amp;quot;xml&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot; indent=&amp;quot;yes&amp;quot;/&amp;gt;&lt;br /&gt; &amp;lt;xsl:strip-space elements=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;xsl:template match=&amp;quot;/&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;opml&amp;gt;&lt;br /&gt;   &amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;outline title=&amp;quot;twitter&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;xsl:for-each select=&amp;quot;/ids/id&amp;quot;&amp;gt;&lt;br /&gt;     &amp;lt;outline&amp;gt;&lt;br /&gt;      &amp;lt;xsl:attribute name=&amp;quot;title&amp;quot;&amp;gt;&amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;&amp;lt;/xsl:attribute&amp;gt;&lt;br /&gt;      &amp;lt;xsl:attribute name=&amp;quot;xmlUrl&amp;quot;&amp;gt;http://twitter.com/statuses/user_timeline/&amp;lt;xsl:value-of select=&amp;quot;.&amp;quot;/&amp;gt;.atom&amp;lt;/xsl:attribute&amp;gt;&lt;br /&gt;     &amp;lt;/outline&amp;gt;&lt;br /&gt;    &amp;lt;/xsl:for-each&amp;gt;&lt;br /&gt;    &amp;lt;/outline&amp;gt;&lt;br /&gt;   &amp;lt;/body&amp;gt;&lt;br /&gt;  &amp;lt;/opml&amp;gt;&lt;br /&gt; &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This contains only the most essential elements of a feed, and the name of each feed is the ID, not the name, but Gooogle Reader imports the feed successfully and some readers can rename the feed from information provided in the RSS/Atom format.&lt;br /&gt;&lt;br /&gt;For an OPML of your friends' favorites, replace "statuses/user_timeline" with favorites.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-1104255048100053535?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/1104255048100053535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=1104255048100053535' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/1104255048100053535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/1104255048100053535'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/06/ultimate-twitter-client.html' title='The ultimate Twitter client'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-6835473277960290446</id><published>2009-02-09T18:57:00.008+02:00</published><updated>2009-02-09T23:15:00.385+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>3 Scala gotchas</title><content type='html'>It's been over a year since I bought my "Programming In Scala" book by Martin Odersky. Since then, a lot has changed. There are now 3 more Scala books in the works: a "Programming Scala" by Venkat Subramaniam (Pragmatic Bookshelf), "Beginning Scala" by David Pollak (Apress) and another "Programming Scala" by Alex Payne (of Twitter fame) and Dean Wampler (by O'Reilly). Scala is the key actor in a couple of new software projects (pun intended), including one at Apache (&lt;a href="http://blog.esme.us"&gt;ESME&lt;/a&gt;, to which yours truly is a committer; ok, I have no shame).&lt;br /&gt;&lt;br /&gt;There's no perfect language, though, and you can't say you know a language until you know its warts. So here's my share of traps, which wasted a lot of my time- I certainly hope you discover them before you waste yours. Of course, these don't mean the language is ill-designed; if only minor corner cases like these can be discovered, this would suggest that a lot of thought has been put in the language.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt; Main method in companion objects &lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="kwa"&gt;object&lt;/span&gt; Test &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; main&lt;span class="sym"&gt;(&lt;/span&gt;args&lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="kwc"&gt;Array&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="kwc"&gt;String&lt;/span&gt;&lt;span class="sym"&gt;]) {&lt;/span&gt;&lt;br /&gt;    println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;Running!&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You copy &amp; paste a simple example and compile it. Great, everything works and you're happy. So now you read about companion objects and decide to use your main method so you can test the companion class. You start with a dummy and (if you're cautious), try to compile right away:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;class&lt;/span&gt; Test &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Good, it compiles. Running it, though, results in a NoSuchMethodException for main. Huh? Well, there's a main method only in singleton objects, not in companion objects.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt; Variables and constants in pattern matching &lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; Extension &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;xml&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="str"&gt;&amp;quot;json&amp;quot;&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; Extension &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Wrong!&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here, you want to match on the contents of a variable. It works as expected: in the above example a MatchError is thrown, as expected. So suddenly you decide that you want to rename the variable...&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; fileExtension &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;xml&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="str"&gt;&amp;quot;json&amp;quot;&lt;/span&gt; match &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;case&lt;/span&gt; fileExtension &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Wrong!&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Boom! Now pattern matching matches things it shouldn't! Actually, it matches everything you throw at it. What has happened? Well, Scala checks the name in order to decide if it's an existing constant (capitalized first letter) or a new variable name it should bind (lower-case first letter). So in the last example a new variable called "fileExtension" was created, which shadows the existing variable name.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt; Always returning Unit from methods&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; test1 &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;test1&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; test2 &lt;span class="sym"&gt;= {&lt;/span&gt;&lt;br /&gt;  &lt;span class="str"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;No surprises here- one method prints a String, the other returns one. So then you suddenly decide that you want only one method to this (contrived) and merge these two:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;def&lt;/span&gt; test &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;test1&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="str"&gt;&amp;quot;test2&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;println&lt;span class="sym"&gt;(&lt;/span&gt;test&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;...and the output is not what is expected: only "test1" is printed. What's wrong here? In Scala, if you omit the equals sign after the method declaration and before the method body, the result is always Unit (same as void in Java).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-6835473277960290446?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/6835473277960290446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=6835473277960290446' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/6835473277960290446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/6835473277960290446'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/02/3-scala-gotchas.html' title='3 Scala gotchas'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-2576403917500800814</id><published>2009-01-28T10:32:00.005+02:00</published><updated>2009-09-17T00:45:48.768+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='channel'/><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scala is static- is Scala dynamic?</title><content type='html'>Despite being statically typed, Scala is not an inflexible language. Smarter folks than me have commented on extending the behavior of classes &lt;a href="http://scala-blogs.org/2007/12/scala-statically-typed-dynamic-language.html"&gt;dynamically&lt;/a&gt; using &lt;a href="http://debasishg.blogspot.com/2008/02/why-i-like-scalas-lexically-scoped-open.html"&gt;implicits&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I want to focus on another feature of Scala which allows for dynamic behavior. In concurrent programming with actors, the default handling involves pattern matching on the messages received. Pattern matching and actor concurrency have been borrowed from Erlang- a dynamic language by nature- and have been one of the key differentiating concepts compared to languages I've learned before.&lt;br /&gt;&lt;br /&gt;When calling a method on a class, you have to know the method signature at compile-time. The types of the parameters you pass must be defined (even through an implicit type conversion). But when you pass a message to an actor (something of an asynchronous method call), you don't need to care what type of class the actor is or what type of messages it can process- at least at compile time:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="kwa"&gt;import&lt;/span&gt; scala&lt;span class="sym"&gt;.&lt;/span&gt;actors&lt;span class="sym"&gt;.&lt;/span&gt;_&lt;br /&gt;&lt;span class="kwa"&gt;import&lt;/span&gt; scala&lt;span class="sym"&gt;.&lt;/span&gt;actors&lt;span class="sym"&gt;.&lt;/span&gt;Actor&lt;span class="sym"&gt;.&lt;/span&gt;_&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; a &lt;span class="sym"&gt;=&lt;/span&gt; actor &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  loop &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;    react &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwa"&gt;case&lt;/span&gt; i&lt;span class="sym"&gt;:&lt;/span&gt; Int &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;Got an integer&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwa"&gt;case&lt;/span&gt; o&lt;span class="sym"&gt;:&lt;/span&gt; AnyRef &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;o&lt;span class="sym"&gt;.&lt;/span&gt;getClass&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;a &lt;span class="sym"&gt;!&lt;/span&gt; &lt;span class="num"&gt;2&lt;/span&gt;&lt;br /&gt;a &lt;span class="sym"&gt;!&lt;/span&gt; &lt;span class="num"&gt;2.8&lt;/span&gt;&lt;br /&gt;a &lt;span class="sym"&gt;!&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;what is this?&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There's an unassuming case denoted by the underscore character (_). This is the so-called catch-all case, the &lt;a href="http://blog.thinkrelevance.com/2008/8/26/java-next-3-dispatch-2"&gt;moral equivalent of Ruby's method_missing&lt;/a&gt;. As you can see, you can send any object to the actor, and all undefined classes can be handled dynamically by this placeholder case.&lt;br /&gt;&lt;br /&gt;Of course, the spirit of Scala doesn't encourage handling patterns using the catch-all method. You can send messages to actors only through a typed scala.actors.Channel:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="kwa"&gt;import&lt;/span&gt; scala&lt;span class="sym"&gt;.&lt;/span&gt;actors&lt;span class="sym"&gt;.&lt;/span&gt;_&lt;br /&gt;&lt;span class="kwa"&gt;import&lt;/span&gt; scala&lt;span class="sym"&gt;.&lt;/span&gt;actors&lt;span class="sym"&gt;.&lt;/span&gt;Actor&lt;span class="sym"&gt;.&lt;/span&gt;_&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;val&lt;/span&gt; c &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Channel&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;Int&lt;span class="sym"&gt;](&lt;/span&gt;actor &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;  loop &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;    react &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwa"&gt;case&lt;/span&gt; _ &lt;span class="sym"&gt;!&lt;/span&gt; _ &lt;span class="sym"&gt;=&amp;gt;&lt;/span&gt; println&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;})&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;c &lt;span class="sym"&gt;!&lt;/span&gt; &lt;span class="num"&gt;2&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once you use this Int-typed Channel, you can only send Int messages to it (unless there are any implicit conversions). For instance this would be caught by the compiler and fail with an error message:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;c ! "2"&lt;br /&gt;&lt;console&gt;:10: error: type mismatch;&lt;br /&gt; found   : java.lang.String("2")&lt;br /&gt; required: Int&lt;br /&gt;       c ! "2"&lt;br /&gt;           ^&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The Channel is constructed using an actor as an argument. This actor can then match by the scala.actors.! class (yes, it's the name of the class) and check which messages have arrived through which channels.&lt;br /&gt;&lt;br /&gt;This took awhile to discover, since the best documentation is in the source itself. If there are any other (and better) idioms for using scala.actors.Channel, I'd be happy to learn them!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-2576403917500800814?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/2576403917500800814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=2576403917500800814' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/2576403917500800814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/2576403917500800814'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/01/scala-is-static-is-scala-dynamic.html' title='Scala is static- is Scala dynamic?'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-1383517082847844519</id><published>2009-01-21T00:14:00.003+02:00</published><updated>2009-01-21T00:56:15.604+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Apply search to following</title><content type='html'>There are still some things that don't make sense in search.twitter.com. For instance, it would be perfectly logical to search in just your followees' timelines. Why, TwitterSpy is already doing it. You could, of course, generate a huge query with "from:" and every possible person you're following, but search.twitter.com restricts the length of the query. Good luck if you have more than 10 friends. Uh, are there people like this after 1 month of using Twitter?&lt;br /&gt;&lt;br /&gt;You could also write a console script, except that you don't want to type your password and reauthenticate once per follower. So doing it from the browser might be a better fit for a quick &amp; dirty approach. This way your session would be reused.&lt;br /&gt;&lt;br /&gt;Here's an educational bookmarklet. You can paste it in the URL bar of Firefox (didn't bother with other browsers) when you've opened twitter.com (won't work if window has a link open under another domain). And you can bookmark it- you thought it would be called a bookmarklet for nothing?&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;javascript&lt;span class="sym"&gt;:&lt;/span&gt;query &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;prompt&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;Twitter search:&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;xmlhttp &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwd"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;xmlhttp&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;open&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;http://twitter.com/statuses/friends.json&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;xmlhttp&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;onload&lt;/span&gt;&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="kwa"&gt;function&lt;/span&gt; &lt;span class="sym"&gt;(){&lt;/span&gt;&lt;br /&gt;        list&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="kwd"&gt;eval&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;xmlhttp&lt;span class="sym"&gt;.&lt;/span&gt;responseText&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;for&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;i&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="num"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt; i&lt;span class="sym"&gt;&amp;lt;&lt;/span&gt;list&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;length&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt; i&lt;span class="sym"&gt;++)&lt;/span&gt;&lt;br /&gt;                &lt;span class="kwc"&gt;window&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;open&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;http://search.twitter.com/search?q=&amp;quot;&lt;/span&gt;&lt;br /&gt;                        &lt;span class="sym"&gt;+&lt;/span&gt; query &lt;span class="sym"&gt;+&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;+from:&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt; list&lt;span class="sym"&gt;[&lt;/span&gt;i&lt;span class="sym"&gt;].&lt;/span&gt;screen_name&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;};&lt;/span&gt;&lt;br /&gt;xmlhttp&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;send&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will open one search window per followee- so don't try this if you have loads of'em. You will hit a limit in Firefox' default config, and you can increase it using the property:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;browser.tabs.maxOpenBeforeWarn&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Still, you will hit a hardware/hardcoded limit if you're not careful with how many people you're following. I told you this only has educational value, right?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-1383517082847844519?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/1383517082847844519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=1383517082847844519' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/1383517082847844519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/1383517082847844519'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/01/apply-search-to-following.html' title='Apply search to following'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-3180804070895233051</id><published>2009-01-09T23:28:00.005+02:00</published><updated>2009-02-09T22:59:06.468+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='slitaz'/><category scheme='http://www.blogger.com/atom/ns#' term='xterm'/><title type='text'>SliTaz: smaller than you think, more useful than you think</title><content type='html'>I started using SliTaz on a USB stick half an year ago just as a workaround to make my laptop with crashed hard-disk usable and try to rescue some of the disk contents. Eventually I ended up keeping the distro as my regular OS. There's a lot to like about it.&lt;br /&gt;&lt;br /&gt;First of all, it's unbelievably small- 25 MB. Yes, in times of Vista, there are graphical OS's &lt;em&gt;and&lt;/em&gt; software distros that small. Yes, they cheat, but with style- the OS is uncompressed using lzma, one of the most efficient compression algorithms. And it has an amazing amount of software, too- Openbox provides a slick GUI and even graphical effects like transparency, Geany is a powerful programmer's editor, Firefox is there, a mail client, torrent client, CD/DVD burner, PDF viewer, mplayer, even Sudoku. I like the choice of lightweight, but stylish programs. Finally, there's a system information applet, which gives you just what you need, and a Debian-like package manager- with a GUI.&lt;br /&gt;&lt;br /&gt;The lack of an office suite is one of the key decisions in SliTaz. These days it is not uncommon to rely on Google Docs as a no-frills office suite. And getting rid of one of the bulkiest pieces of software has a lot of unexpected consequences. The OS is loaded in RAM, which makes it exceptionally fast and responsive, and eliminates a lot of reading/writing to the USB stick, which prolongs its life.&lt;br /&gt;&lt;br /&gt;Why is SliTaz significant? Small is fashionable again due to the resurgent interest in mobile devices and ultra-mini PCs. Especially the Asus EEE PC and similar devices would be a perfect fit.&lt;br /&gt;&lt;br /&gt;In this age of mobility it becomes increasingly important to have a stable environment so you can maximize your productivity. It becomes annoying if you have to set up a new PC every couple of weeks or switch between two different environments. By carrying around a USB stick with your OS, you have not only your documents and portable programs with you- the window manager is the same, you can use the familiar key bindings, the shortcuts and menus are the same. It feels like you're on the same machine.&lt;br /&gt;&lt;br /&gt;Finally, you can regain this lost feeling that you understand what's going on with your OS. You keep it simple, you have just what you need and use everyday, and when you need a rarely used package, just install it from the repository. It won't be there when you reboot (unless you explicitly write RAM to the USB), and security-wise, I like the idea- it's as if you update your software for security vulnerabilities when you need it. It's also harder for malware to set itself up to start on reboot.&lt;br /&gt;&lt;br /&gt;But why did I choose this specific distro? I used DamnSmallLinux for a while, and it was really cool for awhile, but showing its age- most of the software is hopelessly old- kernel 2.4 and... only last year switched to Firefox 2? No, that's not a typo- in times when Firefox 3 is stable, lagging one major version behind seems backwards. If you want to be small, get Firefox 3, use Google Docs, get rid of the office suite.&lt;br /&gt;&lt;br /&gt;More importantly, in DSL there was a 50 MB core of applications, which could not be easily modified and customized. That makes it harder to upgrade as well. In SliTaz you can change everything- remove or upgrade to your heart's content. I can remove more programs, making SliTaz even slimmer.&lt;br /&gt;&lt;br /&gt;The only nitpick I have is that a lot of the configuration utilities assume you have certain base programs. For instance, I wanted to have mrxvt instead of xterm, and get rid of xterm. Eventually wrote a small wrapper for xterm which invokes mrxvt.&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="slc"&gt;#!/bin/sh&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;while&lt;/span&gt; &lt;span class="sym"&gt;[&lt;/span&gt; $&lt;span class="slc"&gt;# -gt 0 ]; do&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;[&lt;/span&gt; &lt;span class="kwb"&gt;$1&lt;/span&gt; &lt;span class="sym"&gt;==&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;-fa&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;];&lt;/span&gt; &lt;span class="kwa"&gt;then&lt;/span&gt;&lt;br /&gt;  ARGS&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;$ARGS -fn&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;elif&lt;/span&gt; &lt;span class="sym"&gt;[&lt;/span&gt; &lt;span class="kwb"&gt;$1&lt;/span&gt; &lt;span class="sym"&gt;==&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;-fs&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;];&lt;/span&gt; &lt;span class="kwa"&gt;then&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwb"&gt;shift&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;elif&lt;/span&gt; &lt;span class="sym"&gt;[&lt;/span&gt; &lt;span class="kwb"&gt;$1&lt;/span&gt; &lt;span class="sym"&gt;==&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;-e&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;];&lt;/span&gt; &lt;span class="kwa"&gt;then&lt;/span&gt;&lt;br /&gt;  ARGS&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;$ARGS -e sh -c '&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;while&lt;/span&gt; &lt;span class="sym"&gt;[&lt;/span&gt; $&lt;span class="slc"&gt;# -gt 0 ]; do&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwb"&gt;shift&lt;/span&gt;&lt;br /&gt;   ARGS&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;$ARGS $1&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;done&lt;/span&gt;&lt;br /&gt;  ARGS&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;$ARGS'&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwb"&gt;break&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;else&lt;/span&gt;&lt;br /&gt;  ARGS&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;$ARGS&lt;/span&gt; &lt;span class="esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;$1&lt;/span&gt;&lt;span class="esc"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;fi&lt;/span&gt;&lt;br /&gt; &lt;span class="kwb"&gt;shift&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;done&lt;/span&gt;&lt;br /&gt;&lt;span class="kwb"&gt;eval exec&lt;/span&gt; mrxvt &lt;span class="kwb"&gt;$ARGS&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-3180804070895233051?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/3180804070895233051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=3180804070895233051' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/3180804070895233051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/3180804070895233051'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2009/01/slitaz-smaller-than-you-think-more.html' title='SliTaz: smaller than you think, more useful than you think'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-3514774768814250738</id><published>2008-09-30T12:07:00.003+03:00</published><updated>2009-02-09T23:03:01.530+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>The browser as a platform</title><content type='html'>Google certainly know how to draw attention. They've even created a &lt;a href="http://blogoscoped.com/google-chrome/"&gt;comic&lt;/a&gt; for dramatic effect to present their new browser. I remember it took a couple of hours to read it because it was constantly timing out because of the immense buzz-generated load on the servers.&lt;br /&gt;&lt;br /&gt;Now after things have calmed down a little, there was a need to have a sober look at Chrome's competitor: Firefox. There was even an &lt;a href="http://arstechnica.com/articles/paedia/mozilla-committed-to-gecko.ars/1"&gt;article&lt;/a&gt; explaining why Mozilla won't change their Gecko rendering engine with Webkit, the engine used in Chrome.&lt;br /&gt;&lt;br /&gt;I'm not saying that Firefox is a better browser, but I think ArsTechnica is onto something. In my humble opinion (I hate abbreviations outside of chat), the fact that XUL can make it so much easier to write extensions is a key factor in its success. Even Steve Yegge mentions, half-jokingly, that Firefox is &lt;a href="http://steve-yegge.blogspot.com/2008/04/xemacs-is-dead-long-live-xemacs.html"&gt;trying to be Emacs&lt;/a&gt;, and if it manages to edit files, he would dump Emacs (and if you know Steve Yegge, he lives for Emacs). Extensibility is again a key criteria here.&lt;br /&gt;&lt;br /&gt;So now even Google has announced that Crome will &lt;a href="http://www.informationweek.com/news/internet/google/showArticle.jhtml?articleID=210602700"&gt;support extensions&lt;/a&gt;. It will surely need them if it is to compete with Firefox.&lt;br /&gt;&lt;br /&gt;I noticed a trend with my personal computing lately. I am using a very thin &lt;a href="http://slitaz.org/en/"&gt;OS on an USB stick&lt;/a&gt;, which is 25-30MB (compressed). A lot of this is due to Firefox, and my externally kept profile is comparable to the OS size- mostly due to addons. Many of these addons are applications in their own right, comfortably using the networking capabilities of Firefox. Here are some of the extensions (some I use, some I don't), which are more like standalone applications than extensions to Firefox' functionality:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;SamePlace&lt;/li&gt; an XMPP &lt;a href="http://www.sameplace.cc/"&gt;instant messenger&lt;/a&gt;, which won the &lt;em&gt;Extend Firefox 2&lt;/em&gt; contest&lt;br /&gt;&lt;li&gt;TwitterFox&lt;/li&gt; a Twitter client&lt;br /&gt;&lt;li&gt;FireFTP&lt;/li&gt; an FTP client&lt;br /&gt;&lt;li&gt;mozImage&lt;/li&gt; an image viewer&lt;br /&gt;&lt;li&gt;Firefly&lt;/li&gt; a file manager&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I'm not even mentioning diffent mail checkers, bookmark synchronizers, etc. Is there a tendency towards extensions which are more independent from the functionality of the browser?&lt;br /&gt;&lt;br /&gt;Eventually, the browser is just a platform, &lt;a href="http://www.linuxjournal.com/content/gacl"&gt;an OS of sorts&lt;/a&gt;, another abstraction layer to make networking transparent for your Web-enabled apps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-3514774768814250738?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/3514774768814250738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=3514774768814250738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/3514774768814250738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/3514774768814250738'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/09/browser-as-platform.html' title='The browser as a platform'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-9085665312154858830</id><published>2008-06-27T09:32:00.005+03:00</published><updated>2009-02-09T23:04:00.030+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='id3v2'/><category scheme='http://www.blogger.com/atom/ns#' term='mp3'/><category scheme='http://www.blogger.com/atom/ns#' term='id3'/><title type='text'>Ruby for mp3 file organizing</title><content type='html'>So there we are, me and my friend &lt;a href="http://twitter.com/oliver"&gt;Oliver&lt;/a&gt;, caught in a business trip. We're already bored of the only decent pub in the village, our families are a long distance away, so what's a developer to do? Code in a programming language he/she's not allowed on the job, of course! Oliver seemed interested in Ruby and I've already done a couple of small scripts with it, so we were curious to see what the fuss is about.&lt;br /&gt;&lt;br /&gt;It goes without saying that if you want to learn to program (in a particular language) you should not rely too much on books. The only way is to find a task you want to have automated, and then code it using your language of choice. Surely, you must pick the task (or the language) carefully, since not all languages are suitable for all tasks.&lt;br /&gt;&lt;br /&gt;One of the things which Oliver has struggled with was organizing all of his podcasts in his player, sorted neatly by directories of author and title. Having found both a hammer and a nail, we were ready to start pounding.&lt;br /&gt;&lt;br /&gt;After a bit of &lt;a href="http://www.braveworld.net/riva/Software/mp3rename.html"&gt;research&lt;/a&gt; we found the mp3info and id3tag Ruby libraries. id3tag had different fields for ID3v1 and ID3v2 data and didn't have write support (not that we needed it). mp3info didn't have ID3v2.2 support, but I found an interesting link about &lt;a href="http://www.unixgods.org/~tilo/ID3/docs/ID3_comparison.html"&gt;ID3 internals&lt;/a&gt;- the format of the fields was something that could be useful.&lt;br /&gt;&lt;br /&gt;After a while our pair programming session has reached a milestone- our script works. It doesn't seem very modular though, so we spend some time making classes and discussing what is the responsibility of each class. Should there be a manager-class? Or should the objects manage themselves? I go with the second approach, and here's the result:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="slc"&gt;# Class for handling information of the mp3 file&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;class&lt;/span&gt; Mp3File&lt;br /&gt;  attr_reader &lt;span class="sym"&gt;:&lt;/span&gt;title&lt;span class="sym"&gt;, :&lt;/span&gt;artist&lt;span class="sym"&gt;, :&lt;/span&gt;album&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; initialize filename&lt;br /&gt;    &amp;#64;artist = &amp;#64;album = &lt;span class="str"&gt;&amp;quot;unknown&amp;quot;&lt;/span&gt;&lt;br /&gt;    &amp;#64;filename = filename&lt;br /&gt;    &amp;#64;title = File&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;basename&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;filename&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;.mp3&amp;quot;&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;    read_attributes&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; title&lt;br /&gt;    &lt;span class="kwd"&gt;sanitize&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&amp;#64;title)&lt;br /&gt;    &lt;span class="kwa"&gt;if&lt;/span&gt; &amp;#64;title == &lt;span class="str"&gt;&amp;quot;unknown&amp;quot;&lt;/span&gt; &lt;span class="kwa"&gt;then&lt;/span&gt; &amp;#64;title = File&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;basename&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&amp;#64;filename&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;.mp3&amp;quot;&lt;/span&gt;) &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;    &amp;#64;title&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; read_attributes&lt;br /&gt;    &lt;span class="kwa"&gt;begin&lt;/span&gt;&lt;br /&gt;      Mp3Info&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;open&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&amp;#64;filename) &lt;span class="kwa"&gt;do&lt;/span&gt; &lt;span class="sym"&gt;|&lt;/span&gt;mp3info&lt;span class="sym"&gt;|&lt;/span&gt;&lt;br /&gt;        &lt;span class="sym"&gt;(&lt;/span&gt;&amp;#64;title&lt;span class="sym"&gt;,&lt;/span&gt; &amp;#64;artist&lt;span class="sym"&gt;,&lt;/span&gt; &amp;#64;album) = %w&lt;span class="sym"&gt;{&lt;/span&gt;title artist album&lt;span class="sym"&gt;}.&lt;/span&gt;collect &lt;span class="sym"&gt;{ |&lt;/span&gt;attrib&lt;span class="sym"&gt;|&lt;/span&gt;&lt;br /&gt;          &lt;span class="kwa"&gt;begin&lt;/span&gt;&lt;br /&gt;            &lt;span class="sym"&gt;(&lt;/span&gt;result = mp3info&lt;span class="sym"&gt;.&lt;/span&gt;tag&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;send&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;attrib))&lt;span class="sym"&gt;.&lt;/span&gt;empty? ? &lt;span class="str"&gt;&amp;quot;unknown&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;:&lt;/span&gt; result&lt;br /&gt;          &lt;span class="kwa"&gt;rescue&lt;/span&gt;&lt;br /&gt;            &lt;span class="str"&gt;&amp;quot;unknown&amp;quot;&lt;/span&gt;&lt;br /&gt;          &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;        &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;rescue&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; sanitize str&lt;br /&gt;    str&lt;span class="sym"&gt;.&lt;/span&gt;tr_s&lt;span class="sym"&gt;!(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;?'&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;_&amp;quot;&lt;/span&gt;)&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; &lt;span class="kwd"&gt;transfer&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;newPath)&lt;br /&gt;    newPath = &lt;span class="kwd"&gt;eval&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'&amp;quot;'&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt; newPath &lt;span class="sym"&gt;+&lt;/span&gt; &lt;span class="str"&gt;'&amp;quot;'&lt;/span&gt;)&lt;br /&gt;    FileUtils&lt;span class="sym"&gt;.&lt;/span&gt;mkdir_p File&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;dirname&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;newPath)&lt;br /&gt;    FileUtils&lt;span class="sym"&gt;.&lt;/span&gt;cp &amp;#64;filename&lt;span class="sym"&gt;,&lt;/span&gt; newPath&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is the class which is initialized with the location of the file and then extracts information about the artist, title and track name. The read_attributes method is meant to show off our new knowledge about the dynamic nature of Ruby- we build a list of methods to invoke on the Mp3Info object, and if no meaningful result, return "unknown". Finally, as the class knows about the current location and mp3 meta-info, it has a method for copying the file to a new location. The new path is passed as a template, where the &lt;code&gt;#@artist&lt;/code&gt;, &lt;code&gt;#@album&lt;/code&gt;, &lt;code&gt;#@title&lt;/code&gt; are substituted with the value of these fields.&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;class&lt;/span&gt; Mp3List&lt;br /&gt;&lt;br /&gt;  attr_reader &lt;span class="sym"&gt;:&lt;/span&gt;files&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; files&lt;br /&gt;    &amp;#64;files&lt;span class="sym"&gt;.&lt;/span&gt;map &lt;span class="sym"&gt;{|&lt;/span&gt;file&lt;span class="sym"&gt;|&lt;/span&gt; Mp3File&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;new&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;file) &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; &lt;span class="kwd"&gt;initialize&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;sourcePath&lt;span class="sym"&gt;,&lt;/span&gt; days = &lt;span class="num"&gt;7&lt;/span&gt;)&lt;br /&gt;    &amp;#64;sourcePath = sourcePath&lt;br /&gt;    &amp;#64;days = days&lt;br /&gt;    &amp;#64;files = read_new&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; read_new&lt;br /&gt;      Dir&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;#&amp;#64;sourcePath/**/*.mp3&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;].&lt;/span&gt;find_all &lt;span class="kwa"&gt;do&lt;/span&gt; &lt;span class="sym"&gt;|&lt;/span&gt;path&lt;span class="sym"&gt;|&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwd"&gt;test&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;?M&lt;span class="sym"&gt;,&lt;/span&gt; path) &lt;span class="sym"&gt;&amp;gt; (&lt;/span&gt;Time&lt;span class="sym"&gt;.&lt;/span&gt;now &lt;span class="sym"&gt;- (&lt;/span&gt;&amp;#64;days &lt;span class="sym"&gt;*&lt;/span&gt; &lt;span class="num"&gt;60&lt;/span&gt; &lt;span class="sym"&gt;*&lt;/span&gt; &lt;span class="num"&gt;60&lt;/span&gt; &lt;span class="sym"&gt;*&lt;/span&gt; &lt;span class="num"&gt;24&lt;/span&gt;))&lt;br /&gt;      &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;def&lt;/span&gt; to_s&lt;br /&gt;    &amp;#64;files&lt;span class="sym"&gt;.&lt;/span&gt;inspect&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here comes the class, which represents a list of mp3 files in a certain directory (and subdirectories), which satisfies some criteria- in this case, how long ago the files were created (modified). Could it be made more general? Certainly, but in a 80-line script? Maybe next time.&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;  list = Mp3List&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;new&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;/home/whoami/Music&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;730&lt;/span&gt;)&lt;br /&gt;  list&lt;span class="sym"&gt;.&lt;/span&gt;files&lt;span class="sym"&gt;.&lt;/span&gt;each &lt;span class="kwa"&gt;do&lt;/span&gt; &lt;span class="sym"&gt;|&lt;/span&gt;mp3&lt;span class="sym"&gt;|&lt;/span&gt;&lt;br /&gt;    &lt;span class="slc"&gt;#~ puts &amp;quot;Processing #{filename}&amp;quot;&lt;/span&gt;&lt;br /&gt;    mp3&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;transfer&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'/tmp/music/#&amp;#64;artist/#&amp;#64;album/#&amp;#64;title.mp3'&lt;/span&gt;)&lt;br /&gt;  &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What's left was an example of how to use these classes. Seems good to me- and best of all, it works.&lt;br /&gt;&lt;br /&gt;The only thing left was to prepare a patch for the mp3info library for ID3v2.2 support. I actually implemented one (still not incorporated in base), and it also initializes the common fields with either the v2 or v1 data, whatever present (v2 still has precedence, if both are present).&lt;br /&gt;&lt;br /&gt;Conclusions from our short session:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Ruby is neat for quick hack jobs&lt;/li&gt;&lt;br /&gt;&lt;li&gt;mp3info does not provide an exhaustive ID3 handling support, but is good enough and workable&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pair programming might not be smooth from the start, but you will learn a lot about yourself&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Organizing your music can sometimes take longer than total time spent looking for your tracks&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You should choose your business trip accomodation place carefully if you can&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-9085665312154858830?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/9085665312154858830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=9085665312154858830' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/9085665312154858830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/9085665312154858830'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/06/ruby-for-mp3-file-organizing.html' title='Ruby for mp3 file organizing'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-8229102050423342274</id><published>2008-06-11T12:04:00.005+03:00</published><updated>2009-02-09T23:04:48.539+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='command_not_found'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>command-not-found handler not only in Ubuntu</title><content type='html'>One of Ubuntu's strengths is that it pays attention to the little things. One of these things, which were important to me lately, was the command_not_found_handler in bash.&lt;br /&gt;&lt;br /&gt;In layman's terms, when you open a terminal in Ubuntu and type a command, which is not on your system, it looks in a database and in a helpful way suggests that you can get this command if you install a certain package. I was using apt-file to provide the same functionality for a while, but this is both easier and more informative (apt-file scans for substrings of the whole path, so spits out a lot of false positives, which are not commands).&lt;br /&gt;&lt;br /&gt;Now as happy as I am in using Ubuntu on my personal machine, I wanted to have this at work, too. I wanted to make it easy for my colleagues who forget to ssh/sudo before executing a command and prepend an appropriate string if the command doesn't work on this machine. Ubuntu can accomplish this trick thanks to a patch of bash, which adds a hook, called command_not_found_handler, but OpenSUSE/SLES is installed at work and this function is missing.&lt;br /&gt;&lt;br /&gt;I had the feeling I can do this in bash only, and then I found &lt;a href="http://blogs.warwick.ac.uk/bweber/entry/untitled_entry_1/"&gt;this blog entry&lt;/a&gt;. Only I didn't quite like how it's implemented, though I liked the idea. Benjamin (the blog author) suggested that the check if the last command was successful is done at each prompt, so it is evaluated even if you press enter on an empty line. Besides, to obtain the last command, the whole history was retrieved only to extract the last entry.&lt;br /&gt;&lt;br /&gt;The reason Benjamin's hook was done like that is that history expansion didn't work in noninteractive shells. I also tried to enable it by using &lt;code&gt;set -H&lt;/code&gt;, but with no luck.&lt;br /&gt;&lt;br /&gt;I thought that using a trap would be better than a prompt command. There was a trap, which would be evaluated only on error, so my first draft was based on the &lt;code&gt;trap ERR&lt;/code&gt; hook. Then I would check if the exit status of the last command was 127 ("command not found" for bash) and... use the command. By chance I found out quickly about BASH_COMMAND, which in traps is evaluated to the currently executing command. But after a lot of failed attempts I found out that it only worked with the DEBUG trap.&lt;br /&gt;&lt;br /&gt;So I used the DEBUG trap and evaluated the last command- if it could be resolved using &lt;code&gt;type&lt;/code&gt;, then it is found. Slower, but more accurate. And it worked!&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;trap 'if ! type -t $BASH_COMMAND &gt;/dev/null; then echo Do something with $BASH_COMMAND; fi' DEBUG&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now my colleagues are happily executing commands, which are only found on remote servers, oblivious to the fact that this command is transparently executing on a host different than their own.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-8229102050423342274?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/8229102050423342274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=8229102050423342274' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/8229102050423342274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/8229102050423342274'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/06/command-not-found-handler-not-only-in.html' title='command-not-found handler not only in Ubuntu'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-1391806583097626555</id><published>2008-06-10T14:04:00.004+03:00</published><updated>2009-02-09T23:07:03.365+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='desktop'/><category scheme='http://www.blogger.com/atom/ns#' term='portable'/><title type='text'>Java Portable Apps</title><content type='html'>&lt;blockquote&gt;&lt;br /&gt;portable&lt;br /&gt;&lt;span style="font-weight:bold;font-style:italic;"&gt;–adjective&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;capable of being transported or conveyed: &lt;span style="font-style:italic;"&gt;a portable stage&lt;/span&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;easily carried or conveyed by hand: &lt;span style="font-style:italic;"&gt;a portable typewriter&lt;/span&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-style:italic;"&gt;Computers&lt;/span&gt;. (of data sets, software, etc.) capable of being used on different computer systems.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;...&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-style:italic;text-align: right;"&gt;Dictionary.com&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So how many definitions of "portable" do your applications of choice satisfy? Having grown up profesionally in the spirit of "write once, run everywhere", I've always wondered how a "portable" application could run only on Windows, as is the case with most of the PortableApps.com. Not that I have anything against portableapps.com, it's a cool idea and a very pragmatic software suite is offered.&lt;br /&gt;&lt;br /&gt;But I happen to work on Linux and my colleagues usually work on Windows, so if I want my applications-on-a-stick to be truly portable, they need to run on any platform. I need portable in the sense of "running on any operating system". Thus an obvious choice is Java- it's usually not the first choice for a desktop application, but here its intended purpose fits the bill nicely. And I don't need &lt;span style="font-style:italic;"&gt;all&lt;/span&gt; operating systems- honestly, who would lend me their Mac? Come on, it's too personal to give to anyone ;-) This means I can have a JRE for Linux and Windows on my stick (in case it's not installed), and I'm set.&lt;br /&gt;&lt;br /&gt;Of course, the task of finding the actual applications is the difficult one. They are not all completely portable in the sense of "not modifying anything on the hard disk", but most of them could be configured to run with settings from the USB. I also needed to run all of these on machines without administrator privileges. Most (with a few exceptions) are open-source:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Organizer: &lt;a href="http://www.thinkingrock.com.au/"&gt;ThinkingRock&lt;/a&gt;&lt;/li&gt; An outstanding application for organizing your tasks according to the &lt;a href="http://en.wikipedia.org/wiki/Getting_things_done"&gt;Getting Things Done&lt;/a&gt; method. I am now so addicted to this app that I can't leave anywhere without it- I feel lost withot my next actions list. &lt;span style="font-style:italic;"&gt;Con&lt;/span&gt;- it is the least portable in the sense that it creates some .java entries, but mostly related to layout- something I can live without.&lt;br /&gt;&lt;li&gt;Editor: &lt;a href="http://www.jedit.org/"&gt;jEdit&lt;/a&gt;&lt;/li&gt; One of my all-time favorite editors, I really doubt there's much this editor can't do. With all of its useful plugins, it doubles as a mini-IDE. I run it with a command-line option to use the settings on the USB stick and the settings include the option to download my plugins there, so I have them with me as well.&lt;br /&gt;&lt;li&gt;Mind Mapper: &lt;a href="http://freemind.sourceforge.net"&gt;FreeMind&lt;/a&gt;&lt;/li&gt; Another immensely useful program, FreeMind is an open-source mind-mapping application, indispensable for loads of stuff like notes, brainstorming, personal database, task-manager...&lt;br /&gt;&lt;li&gt;Outliners&lt;/li&gt; I couldn't choose between the extensibility and import/export capabilities of &lt;a href="http://outliner.sourceforge.net/"&gt;JOE&lt;/a&gt; (Java Outline Editor) and the rich text support of &lt;a href="http://jreepad.sourceforge.net/"&gt;Jreepad&lt;/a&gt; (including Textile markup), so I have both. I really wish JOE's default shortcuts were a bit less awkward, but it's a great tool even though there's no development on it for several years now.&lt;br /&gt;&lt;li&gt;File Manager: &lt;a href="http://www.mucommander.com/"&gt;muCommander&lt;/a&gt;&lt;/li&gt; A couple of years ago I would be really bothered by the idea of using a Java file manager (Java doesn't have the best OS integration, you know). Now I'm happy to use this really nice lightweight commander clone. It has transparent filesystem support for popular archives and remote protocols (FTP, Windows shares, SFTP).&lt;br /&gt;&lt;li&gt;Disk space manager: &lt;a href="http://www.jgoodies.com/freeware/jdiskreport/"&gt;JDiskReport&lt;/a&gt;&lt;/li&gt; Warning: not open-source, but free for personal use. Generates very nice pie charts about filesystem usage though, and even has a Web Start version. I still want to be able to check my disk space when I'm not online, so it has a convenient place on my USB thumb drive.&lt;br /&gt;&lt;li&gt;Media organizer: &lt;a href="http://mediasort.sourceforge.net/"&gt;MediaSort&lt;/a&gt;&lt;/li&gt; Organizes music and pictures into directories/filenames based on tags inside these media files. Pretty nifty. I used to do that with a clunky one-liner script calling &lt;code&gt;jhead&lt;/code&gt; for JPEG files and a custom Ruby script for MP3 files, but this proved to be a nicer general solution.&lt;br /&gt;&lt;li&gt;File Synchronization: &lt;a href="http://jfilesync.sourceforge.net/"&gt;JFileSync&lt;/a&gt;&lt;/li&gt; I carry this around in case I don't have rsync handy. Its GUI looks very nice for syncing directories to and from my USB key.&lt;br /&gt;&lt;li&gt;Version Control: &lt;a href="http://www.syntevo.com/smartsvn/index.html"&gt;SmartSVN&lt;/a&gt;&lt;/li&gt; Version control is must-have for a developer. SmartSVN is not open-source, but has a version, which is free for personal use. This was the only Subversion client I could find, which would work on Windows without administrative privileges, &lt;span style="font-style:italic;"&gt;and&lt;/span&gt; use Windows authentication.&lt;br /&gt;&lt;li&gt;Port forwarders&lt;/li&gt; Network connectivity is important to me so I have an assortment of port forwarding applications for different purposes. &lt;a href="https://sourceforge.net/projects/jportforwarder"&gt;JPortForwarder&lt;/a&gt; is a simple port forwarder (site says it's multithreaded), so I don't have to rewrite one every time. &lt;a href="http://cs.nyu.edu/brw215/plugproxy/"&gt;PlugProxy&lt;/a&gt; is a really cool way to debug network applications, as it shows the network traffic as it transparently redirects it. &lt;a href="http://www.winton.org.uk/zebedee/download.html"&gt;jzbd&lt;/a&gt; adds encryption to forwarding when I'm worried about security. These are not updated in a long time, but what could you improve in a port forwarder?&lt;br /&gt;&lt;li&gt;Port Scanners&lt;/li&gt; Yeah, I know the low-level scanning options of NMap are out of Java's reach, but still. &lt;a href="http://antaki.ca/code/java/japs/"&gt;JAPS&lt;/a&gt; makes a fast concurrent scan of a single host, while &lt;a href="http://tomsalmon.com/jmap.php"&gt;JMap&lt;/a&gt; can scan a subnet (no, it's got nothing to do with Sun's &lt;a href="http://java.sun.com/javase/6/docs/technotes/tools/share/jmap.html"&gt;post-mortem memory analysis tool&lt;/a&gt;).&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;This set of programs proved especially useful when my laptop's hard drive reached the end of its intense life. Using a &lt;a href="http://www.damnsmalllinux.org/"&gt;Damn Small Linux&lt;/a&gt; to boot from the USB disk along with these applications really decreased the time I could get productive again- without a hard disk- until I got a new hard-drive. To top it off, I could boot DSL in Windows, emulated by &lt;a href="http://www.h7.dion.ne.jp/~qemu-win/"&gt;qemu&lt;/a&gt;- but DSL can really deserves a blog post on its own.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Update:&lt;/span&gt; This blog prompted me to do some more research and I found this great &lt;a href="http://www.javalobby.org/java/forums/m91956049.html"&gt;thread on Javalobby&lt;/a&gt; about Java Desktop Apps. There's at least one new cool app I am going away with- &lt;a href="http://www.kiyut.com/products/ekspos/index.html"&gt;ekspos&lt;/a&gt; image viewer. It even has Picasa integration!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-1391806583097626555?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/1391806583097626555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=1391806583097626555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/1391806583097626555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/1391806583097626555'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/06/java-portable-apps.html' title='Java Portable Apps'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-2783967893811134918</id><published>2008-05-08T14:08:00.004+03:00</published><updated>2009-02-09T23:08:16.237+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='muCommander'/><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><title type='text'>SSH key-based authentication in Java</title><content type='html'>Yet again the next project of the week was the intersection of work and play (kinda). There was the upcoming project where I would need to exercise remote control using SSH. And there was the next program I was toying with: a nice lightweight &lt;a href="http://www.mucommander.com/"&gt;commander clone&lt;/a&gt; written in Java. What's the common theme here? Well, muCommander has several virtual filesystems, including one for SFTP (and if you didn't know it before, that's a file transfer protocol for SSH).&lt;br /&gt;&lt;br /&gt;But muCommander didn't use public key authentication, and I have disabled password-based authentication on my home SSH server. So there was the opportunity to play around with &lt;a href="http://sshtools.sourceforge.net/"&gt;J2SSH&lt;/a&gt; (which muCommander was using) and both implement key-based authentication in my current file manager and explore one of the libraries for my next project. OK, maybe not applicable for my work project, because J2SSH is GPL, but I can get to play, OK?&lt;br /&gt;&lt;br /&gt;With license questions out of the way, we can get down to business. And it is not difficult at all, as the j2ssh/examples directory contains a PublicKeyConnect.java. You just need to instantiate a &lt;code&gt;com.sshtools.j2ssh.SshClient&lt;/code&gt;, call &lt;code&gt;connect&lt;/code&gt;, passing the hostname as a String and authenticate using the method... which was it... ah yes &lt;code&gt;authenticate&lt;/code&gt;, passing a &lt;code&gt;com.sshtools.j2ssh.authentication.SshAuthenticationClient&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Now getting this &lt;code&gt;SshAuthenticationClient&lt;/code&gt; is the fun part. In our case, we are using the &lt;code&gt;com.sshtools.j2ssh.authentication.PublicKeyAuthenticationClient&lt;/code&gt; and we need several more steps to prep it up. After instantiating it, we need to call &lt;code&gt;setUsername&lt;/code&gt; with a String (can't tell you what it stands for). Then we need to set the private key itself using the &lt;code&gt;setKey&lt;/code&gt; method and we're &lt;s&gt;ready&lt;/s&gt;.&lt;br /&gt;&lt;br /&gt;What? &lt;code&gt;setKey&lt;/code&gt; expects a parameter? Well yes it does, and it's another of those j2ssh classes: &lt;code&gt;com.sshtools.j2ssh.transport.publickey.SshPrivateKey&lt;/code&gt;. But we seem to be stuck here, as you can't instantiate &lt;code&gt;SshPrivateKey&lt;/code&gt;- it's abstract. What does this mean? Argh, never mind, you can't instantiate it. Try it. See? Told ya so.&lt;br /&gt;&lt;br /&gt;So then we see there's this similarly named &lt;code&gt;com.sshtools.j2ssh.transport.publickey.SshPrivateKeyFile&lt;/code&gt;. Might it have something to do with our &lt;code&gt;SshPrivateKey&lt;/code&gt;? Yes, as it turns out, it has a method &lt;code&gt;toPrivateKey&lt;/code&gt; (takes a passphrase as a String- you do use passphrases, don't you?), and returns our most wanted &lt;code&gt;SshPrivateKey&lt;/code&gt;. What's that you're saying? You can't instantiate &lt;code&gt;SshPrivateKeyFile&lt;/code&gt; either? Fear not, because it has a static method &lt;code&gt;parse&lt;/code&gt;, which overloaded to accept both a File and a byte array with the actual private key file or data.&lt;br /&gt;&lt;br /&gt;If you couldn't follow this convoluted line of thought (I couldn't), here's the code, as taken from the patch of muCommander:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;PublicKeyAuthenticationClient pk &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwd"&gt;PublicKeyAuthenticationClient&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;pk&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;setUsername&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;credentials&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getLogin&lt;/span&gt;&lt;span class="sym"&gt;());&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;SshPrivateKey key &lt;span class="sym"&gt;=&lt;/span&gt; null&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// Throw an AuthException if problems with private key file&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;try&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;    SshPrivateKeyFile file &lt;span class="sym"&gt;=&lt;/span&gt; SshPrivateKeyFile&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;parse&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;File&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;privateKeyPath&lt;span class="sym"&gt;));&lt;/span&gt;&lt;br /&gt;    key &lt;span class="sym"&gt;=&lt;/span&gt; file&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;toPrivateKey&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;credentials&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getPassword&lt;/span&gt;&lt;span class="sym"&gt;());&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt; &lt;span class="kwa"&gt;catch&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;InvalidSshKeyException iske&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;throw new&lt;/span&gt; &lt;span class="kwd"&gt;AuthException&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;realm&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Invalid private key file or passphrase&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;  &lt;span class="slc"&gt;// Todo: localize this entry&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt; &lt;span class="kwa"&gt;catch&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;IOException&lt;/span&gt; ioe&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;throw new&lt;/span&gt; &lt;span class="kwd"&gt;AuthException&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;realm&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Error reading private key file&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;  &lt;span class="slc"&gt;// Todo: localize this entry&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;pk&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;setKey&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;key&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now if &lt;code&gt;sshClient.authenticate&lt;/code&gt; returns &lt;code&gt;AuthenticationProtocolState.COMPLETE&lt;/code&gt;, you're ready to go. You can open a shell or an &lt;code&gt;SftpClient&lt;/code&gt;. Mission accomplished.&lt;br /&gt;&lt;br /&gt;If you had the urge to download the muCommander source code and apply this patch, no need to: it's already &lt;a href="http://www.mucommander.com/forums/viewtopic.php?f=8&amp;t=729"&gt;implemented in CVS&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-2783967893811134918?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/2783967893811134918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=2783967893811134918' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/2783967893811134918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/2783967893811134918'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/05/ssh-key-based-authentication-in-java.html' title='SSH key-based authentication in Java'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-7478601785620728803</id><published>2008-04-18T11:48:00.002+03:00</published><updated>2008-04-18T13:00:32.296+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Twitter: do you follow me?</title><content type='html'>This week's hacking task was to implement a "follow all" function for Twitter.&lt;br /&gt;&lt;br /&gt;Even for Twitter users, this needs some explanation: the follow functionality now means "enable notifications". However, the command interface in IM/SMS wasn't changed, so the command name remains "follow". For brevity, I will use the word "follow" instead of "enable notifications".&lt;br /&gt;&lt;br /&gt;The reason for having this command is that there used to be a function "follow all" in Twitter. It used to instantly turn on notifications for all your friends (users you're following in new terminology). Now there's a user, called "all" and the function doesn't work (ok, maybe that's not the real reason). This put an end to a very useful feature for users who rely often on the Twitter IM integration.&lt;br /&gt;&lt;br /&gt;Having a quick look at the &lt;a href="http://groups.google.com/group/twitter-development-talk/web/api-documentation"&gt;Twitter API&lt;/a&gt; it seemed pretty straightforward to fetch all users and enable notifications for all of them one by one. It would be fairly slow, but there was no information in the user list whether notifications are enabled for a user or not. This would have eliminated the need to send requests for users, for whom we already have notifications enabled. Ah well...&lt;br /&gt;&lt;br /&gt;The first tool I reach in my toolbox is Ruby. I tried using JSON, but had to give up- I simply couldn't handle Unicode issues:&lt;br /&gt;&lt;br /&gt;/usr/lib/ruby/1.8/json.rb:288:in `chr': 1090 out of char range (RangeError)&lt;br /&gt;&lt;br /&gt;It turned that it was much smoother with REXML, and it really is a superior library for XML processing (Python's are either easy or full-featured, REXML seems to be both).&lt;br /&gt;&lt;br /&gt;I initially took the path of using 'open-uri' for fetching the data over http. After all, it handled even http base authentication and abstracted the nitty-gritty details, and so was easy to use.&lt;br /&gt;&lt;br /&gt;But it isn't meant to be used for more fine-grained control, and I soon ran into performance problems, which required special treatment. I found that I quickly exhausted the rate limit of the Twitter API- it's only 70 requests per hour, and with one request per user... you get the picture.  The web interface wasn't actually subject to such restrictions, so I wanted to check how it's doing it. A slightly different URL, but worked like a charm, and rate limits seemed to be no problem now!&lt;br /&gt;&lt;br /&gt;This time, though, the script ran much longer- 80 seconds compared to about 30 before the change. I analyzed the requests and found out that each received a 302 response, forwarding back to the home page. That meant that open-uri was downloading the whole home page for each user!&lt;br /&gt;&lt;br /&gt;At that point open-uri had to go and make way for Net::HTTP. It took more lines to rewrite it, but now I had the choice not to follow redirect responses. I only needed to toggle notifications and didn't care what I got back (as long as it's not an error code). In addition, I could use the same Net::HTTP object, meaning that I use the same HTTP keep-alive connection (not sure if open-uri can do this).&lt;br /&gt;&lt;br /&gt;And here's the result- dirty, but still quick. You can configure the action to "follow" or "leave" (to disable all notifications). You need to configure the user and password. Putting the configuration options as command-line arguments is left as an exercise to the reader.&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="slc"&gt;#!/usr/bin/env ruby&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;require &lt;span class="str"&gt;'uri'&lt;/span&gt;&lt;br /&gt;require &lt;span class="str"&gt;'net/http'&lt;/span&gt;&lt;br /&gt;require &lt;span class="str"&gt;'rexml/document'&lt;/span&gt;&lt;br /&gt;include REXML&lt;br /&gt;&lt;br /&gt;user = &lt;span class="str"&gt;&amp;quot;lazyuser&amp;quot;&lt;/span&gt;&lt;br /&gt;pass = &lt;span class="str"&gt;&amp;quot;notmypassword&amp;quot;&lt;/span&gt;&lt;br /&gt;action = &lt;span class="str"&gt;&amp;quot;follow&amp;quot;&lt;/span&gt;&lt;br /&gt;PAGE_USERS = &lt;span class="num"&gt;100&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Net&lt;span class="sym"&gt;::&lt;/span&gt;HTTP&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;start&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;twitter.com&amp;quot;&lt;/span&gt;) &lt;span class="kwa"&gt;do&lt;/span&gt; &lt;span class="sym"&gt;|&lt;/span&gt;http&lt;span class="sym"&gt;|&lt;/span&gt;&lt;br /&gt;    page = &lt;span class="num"&gt;0&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;begin&lt;/span&gt;&lt;br /&gt;        page &lt;span class="sym"&gt;+&lt;/span&gt;= &lt;span class="num"&gt;1&lt;/span&gt;&lt;br /&gt;        req = Net&lt;span class="sym"&gt;::&lt;/span&gt;HTTP&lt;span class="sym"&gt;::&lt;/span&gt;Get&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;new&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;/statuses/friends.xml?lite=true&amp;amp;page=#{page}&amp;quot;&lt;/span&gt;)&lt;br /&gt;        req&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;basic_auth&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;user&lt;span class="sym"&gt;,&lt;/span&gt; pass)&lt;br /&gt;&lt;br /&gt;        doc = Document&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;new&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;http&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;request&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;req)&lt;span class="sym"&gt;.&lt;/span&gt;body)&lt;br /&gt;        ids = doc&lt;span class="sym"&gt;.&lt;/span&gt;elements&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;to_a&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;/users/user/id&amp;quot;&lt;/span&gt;)&lt;br /&gt;        ids&lt;span class="sym"&gt;.&lt;/span&gt;each &lt;span class="kwa"&gt;do&lt;/span&gt; &lt;span class="sym"&gt;|&lt;/span&gt;entry&lt;span class="sym"&gt;|&lt;/span&gt;&lt;br /&gt;            req_follow = Net&lt;span class="sym"&gt;::&lt;/span&gt;HTTP&lt;span class="sym"&gt;::&lt;/span&gt;Get&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;new&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;/friends/#{action}/&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt; entry&lt;span class="sym"&gt;.&lt;/span&gt;text)&lt;br /&gt;            req_follow&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;basic_auth&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;user&lt;span class="sym"&gt;,&lt;/span&gt; pass)&lt;br /&gt;            http&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;request&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;req_follow)&lt;br /&gt;        &lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;end while&lt;/span&gt; ids&lt;span class="sym"&gt;.&lt;/span&gt;size == PAGE_USERS&lt;br /&gt;&lt;span class="kwa"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-7478601785620728803?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/7478601785620728803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=7478601785620728803' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7478601785620728803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/7478601785620728803'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/04/twitter-do-you-follow-me.html' title='Twitter: do you follow me?'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-4242884401985109848</id><published>2008-04-16T14:40:00.003+03:00</published><updated>2008-04-16T15:51:28.173+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>XML escape</title><content type='html'>Friday afternoon is a prime time for blitz-tasks and a rich opportunity for your hacking one-liner &lt;s&gt;5K1LLz&lt;/s&gt; skills.&lt;br /&gt;&lt;br /&gt;This Friday the finish-up task came from a colleague, who had to leave in half an hour to catch the plane. There's a big several-megabyte XML file and all characters in it had to be escaped, I presume for preparation to be sent over the wire (read http).&lt;br /&gt;&lt;br /&gt;Problem is, a certain Windows editor (does it really qualify that definition?) hangs when opening files bigger than 1234KB, and writing a Java program would take a fairly long time compared to the alternatives. Not to mention that many programmers could write the Java program even less memory-efficiently than the joke of an editor that Notepad is (there, I said it). And Java is not very forgiving on memory problems.&lt;br /&gt;&lt;br /&gt;But what are the alternatives? As the Perl manual page says, "The three principal virtues of a programmer are Laziness, Impatience, and Hubris." Being a lazy programmer, I tried to see if somebody else had already written a utility to do this (there was zero chance that there wasn't one), and if it was available. First I found this &lt;a href="http://wscep.sourceforge.net/xmlescaping.html"&gt;eclipse plugin&lt;/a&gt;. However, pasting megabytes into a text box didn't make me confident that it would work.&lt;br /&gt;&lt;br /&gt;There was also the &lt;a href="http://linux.die.net/man/1/xmlstarlet"&gt;xmlstarlet&lt;/a&gt; package, which would have done a wonderful job, had it been installed on the old servers where the file could be easily transferred. But it wasn't, while it would take too long to copy it to my machine and back just to convert the file. It would also be hard to find an appropriate package for that old Linux version. No, that's not for impatient programmers.&lt;br /&gt;&lt;br /&gt;The next thought I had was: why spend effort on trying to install a package when with Ruby I could do this in a one-liner. Of course, I have nothing against Python, but if there's one thing nobody would argue is that it doesn't fare well against Ruby when it comes to writing one-liners. Anyway, Ruby wasn't installed there either (note to self: this must be amended).&lt;br /&gt;&lt;br /&gt;The clock was ticking. So Python it is, and instead of an obfuscated one-liner I convinced myself to write many short readable lines. I hadn't done serious XML processing in Python for a while, but a google search away the answer came to me. It was really insultingly simple, but given enough hubris one could turn even this meager piece of code into a rambling blog post:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="slc"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;from&lt;/span&gt; xml&lt;span class="sym"&gt;.&lt;/span&gt;sax&lt;span class="sym"&gt;.&lt;/span&gt;saxutils &lt;span class="kwa"&gt;import&lt;/span&gt; escape&lt;br /&gt;&lt;span class="kwa"&gt;from&lt;/span&gt; sys &lt;span class="kwa"&gt;import&lt;/span&gt; stdin&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;for&lt;/span&gt; line &lt;span class="kwa"&gt;in&lt;/span&gt; stdin&lt;span class="sym"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;print&lt;/span&gt; &lt;span class="kwd"&gt;escape&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;line&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-4242884401985109848?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/4242884401985109848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=4242884401985109848' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/4242884401985109848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/4242884401985109848'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/04/xml-escape.html' title='XML escape'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-469794096328381406</id><published>2008-04-10T18:28:00.007+03:00</published><updated>2008-04-11T23:45:53.321+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='BeanShell'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenOffice'/><title type='text'>Instant evaluation of Java code in OpenOffice</title><content type='html'>At the end of last year I had agreed to update a 4-day Java learning course to reflect the changes in Java 5 and 6. The problems with that were:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;The course material was long- over 300 pages already&lt;/li&gt; I know what you're thinking- that's 75 pages per freakin' day (not counting the exercises). All right, next time I'll publish a book&lt;br /&gt; &lt;li&gt;There was a deadline&lt;/li&gt; ...tight as it usually is, considering it had to be done in off-work hours.&lt;br /&gt; &lt;li&gt;My first son was going to be born &lt;em&gt;before&lt;/em&gt; the deadline&lt;/li&gt; Uh-oh, now that should have made me worry.&lt;br /&gt; &lt;li&gt;The document was in Word .doc format&lt;/li&gt; A big no-no. Maybe you have your reasons, but I have mine- I will never, ever write or maintain a significant piece of documentation like that (or insignificant, for that matter) ever again. And I mean it.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I really considered moving the contents to another format- be it LaTeX, docbook or a lightweight markup language like reStructuredText or asciidoc (a topic for another post). Now being out of time meant that I couldn't.&lt;br /&gt;&lt;br /&gt;I should have also updated each and every single example for the new language syntax (where relevant) and test that it works. Now last I counted that was 254 snippets of code. OK, it could happen that one example was split across several snippets, but that's nonetheless tons of work- copy the code, paste it in a text editor, save it, compile it, run it, see if the results are the ones expected. If any step fails, rinse and repeat. Dirty work.&lt;br /&gt;&lt;br /&gt;The reason I miss simple text formats is that it's so much easier to automate things. For instance, in the document you could include all your source files, which are located separately and tested automatically in one go.&lt;br /&gt;&lt;br /&gt;But I didn't have this option. I needed to find some way to automate this. And the answer came from the very material I was going to present- Java Compiler API.&lt;br /&gt;&lt;br /&gt;A frequently neglected feature in Java 6, Compiler API provided language libraries to control the process of compiling right in your Java code. So far you needed to save into a file and invoke a separate process to do that- really a workaround. If you've ever used &lt;code&gt;eval&lt;/code&gt; in scripting language, you're going to miss instant evaluation sorely. With the new compiler API, well, you're still gonna miss it, but at least compiling is no longer a hack. Besides, control of the compiler now meant that your performance is going to be much better as you can even compile from a string in memory.&lt;br /&gt;&lt;br /&gt;The idea began to form- I could define a BeanShell macro in OpenOffice. If we're using OpenOffice integrated with Java 6, then BeanShell will have access to the compiler APIs as well. The macro would compile a class from the selected text in the document (in memory) and load it (still in memory), then run it and display the results. This would certainly make testing the examples faster.&lt;br /&gt;&lt;br /&gt;I'm usually lazy enough to first search for a similar solution (even if finding that solution takes more effort than writing it). The first source I came across about in-memory compilation was in the API documentation of &lt;a href="http://java.sun.com/javase/6/docs/api/javax/tools/JavaCompiler.html"&gt;JavaCompiler&lt;/a&gt;. It was a good start, it used SimpleJavaFileObject to read source from a String, but the class file was still compiled and saved to disk.&lt;br /&gt;&lt;br /&gt;Along the same lines was the &lt;a href="http://www.javabeat.net/javabeat/java6/articles/java_6_0_compiler_api_4.php"&gt;detailed article in JavaBeat&lt;/a&gt;- it showed how to compile from String using a SimpleJavaFileObject.&lt;br /&gt;&lt;br /&gt;I knew there had to be more you need to do. The class file always appeared on disk. I was not very keen on the idea of writing a file to disk (implicitly or explicitly). It's slower, it's less secure and often more effort. I found what I was looking for in the &lt;a href="http://www.velocityreviews.com/forums/t318697-javacompilertool.html"&gt;velocityreviews forums&lt;/a&gt;. Bot I really struck gold with &lt;a href="http://fivedots.coe.psu.ac.th/~ad/jg/javaArt1/onTheFlyArt1.pdf"&gt;this really detailed document&lt;/a&gt;, which described almost exactly what I wanted to do. It's about visualizing the Java bytecode by the way.&lt;br /&gt;&lt;br /&gt;There was one more point. I was wondering which graphical widget to use, and it turns out I could have a popup box using both the OpenOffice APIs or normal Java AWT/Swing. I chose OpenOffice, because the look and feel was better integrated- and because it was different than the Java libraries, which I already knew. I had to read a bit in the &lt;a href="http://api.openoffice.org/docs/DevelopersGuide/Text/Text.xhtml#1_Text_Documents"&gt;OpenOffice developer's guide&lt;/a&gt;, but it finally worked out.&lt;br /&gt;&lt;br /&gt;So my final macro began to take shape. I first had to create the familiar SimpleJavaFileObject. I had to construct it with a String as an argument. The crucial point was to override the getCharContent method so it returns the class field with the String.&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;class&lt;/span&gt; JavaObjectFromString &lt;span class="kwa"&gt;extends&lt;/span&gt; SimpleJavaFileObject&lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;private&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt; contents &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;public&lt;/span&gt; &lt;span class="kwd"&gt;JavaObjectFromString&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;String&lt;/span&gt; className&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt; contents&lt;span class="sym"&gt;)&lt;/span&gt; &lt;span class="kwa"&gt;throws&lt;/span&gt; &lt;span class="kwc"&gt;Exception&lt;/span&gt;&lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;super&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;URI&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;className &lt;span class="sym"&gt;+&lt;/span&gt; Kind&lt;span class="sym"&gt;.&lt;/span&gt;SOURCE&lt;span class="sym"&gt;.&lt;/span&gt;extension&lt;span class="sym"&gt;),&lt;/span&gt; Kind&lt;span class="sym"&gt;.&lt;/span&gt;SOURCE&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;this&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;contents &lt;span class="sym"&gt;=&lt;/span&gt; contents&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;public&lt;/span&gt; &lt;span class="kwc"&gt;CharSequence&lt;/span&gt; &lt;span class="kwd"&gt;getCharContent&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwb"&gt;boolean&lt;/span&gt; ignoreEncodingErrors&lt;span class="sym"&gt;)&lt;/span&gt; &lt;span class="kwa"&gt;throws&lt;/span&gt; &lt;span class="kwc"&gt;IOException&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;return&lt;/span&gt; contents&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What I discovered in the last two sources was that I would need to implement a file manager, preferrably by extending ForwardingJavaFileManager. However, it needs another reimplementation of SimpleJavaFileObject, but this time for the class data itself, not the source. The important thing here is to override openInputStream and openOutputStream to correct the notion of the class about where its data is located:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwa"&gt;static class&lt;/span&gt; RAMJavaFileObject &lt;span class="kwa"&gt;extends&lt;/span&gt; SimpleJavaFileObject &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwd"&gt;RAMJavaFileObject&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;String&lt;/span&gt; name&lt;span class="sym"&gt;,&lt;/span&gt; Kind kind&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;super&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;URI&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;create&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;string:///&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt; name&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;replace&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'.'&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt;&lt;span class="str"&gt;'/'&lt;/span&gt;&lt;span class="sym"&gt;) +&lt;/span&gt; Kind&lt;span class="sym"&gt;.&lt;/span&gt;SOURCE&lt;span class="sym"&gt;.&lt;/span&gt;extension&lt;span class="sym"&gt;),&lt;/span&gt; kind&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwc"&gt;ByteArrayOutputStream&lt;/span&gt; baos&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;public&lt;/span&gt; &lt;span class="kwc"&gt;CharSequence&lt;/span&gt; &lt;span class="kwd"&gt;getCharContent&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwb"&gt;boolean&lt;/span&gt; ignoreEncodingErrors&lt;span class="sym"&gt;)&lt;/span&gt; &lt;span class="kwa"&gt;throws&lt;/span&gt; &lt;span class="kwc"&gt;IOException&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;IllegalStateException&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;UnsupportedOperationException&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;throw new&lt;/span&gt; &lt;span class="kwc"&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;public&lt;/span&gt; &lt;span class="kwc"&gt;InputStream&lt;/span&gt; &lt;span class="kwd"&gt;openInputStream&lt;/span&gt;&lt;span class="sym"&gt;()&lt;/span&gt; &lt;span class="kwa"&gt;throws&lt;/span&gt; &lt;span class="kwc"&gt;IOException&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;IllegalStateException&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;UnsupportedOperationException&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;return new&lt;/span&gt; &lt;span class="kwc"&gt;ByteArrayInputStream&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;baos&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;toByteArray&lt;/span&gt;&lt;span class="sym"&gt;());&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;public&lt;/span&gt; &lt;span class="kwc"&gt;OutputStream&lt;/span&gt; &lt;span class="kwd"&gt;openOutputStream&lt;/span&gt;&lt;span class="sym"&gt;()&lt;/span&gt; &lt;span class="kwa"&gt;throws&lt;/span&gt; &lt;span class="kwc"&gt;IOException&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;IllegalStateException&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;UnsupportedOperationException&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;return&lt;/span&gt; baos &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;ByteArrayOutputStream&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we have everything necessary to extend on our ForwardinJavaFileManager so that it uses our implementation of in-memory class data. Note that we create a HashMap to be used later:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;output &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;HashMap&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;class&lt;/span&gt; RAMFileManager &lt;span class="kwa"&gt;extends&lt;/span&gt; ForwardingJavaFileManager&lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwd"&gt;RAMFileManager&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;JavaCompiler compiler&lt;span class="sym"&gt;){&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;super&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;compiler&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getStandardFileManager&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt;&lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt;&lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;));&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;public&lt;/span&gt; JavaFileObject &lt;span class="kwd"&gt;getJavaFileForOutput&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;Location location&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt; name&lt;span class="sym"&gt;,&lt;/span&gt; Kind kind&lt;span class="sym"&gt;,&lt;/span&gt; FileObject sibling&lt;span class="sym"&gt;)&lt;/span&gt; &lt;span class="kwa"&gt;throws&lt;/span&gt; java&lt;span class="sym"&gt;.&lt;/span&gt;io&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;IOException&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        JavaFileObject jfo &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwd"&gt;RAMJavaFileObject&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;name&lt;span class="sym"&gt;,&lt;/span&gt; kind&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        output&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;put&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;name&lt;span class="sym"&gt;,&lt;/span&gt; jfo&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;return&lt;/span&gt; jfo&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The last thing I define is a small utility method which just returns the String of the class. As you can see, I've made it convenient to select code fragments and the macro will create the necessary framework around them- a container class and a main method, if need be:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;SimpleJavaFileObject &lt;span class="kwd"&gt;getJavaFileContentsAsString&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;String&lt;/span&gt; outside&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt; inClass&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;String&lt;/span&gt; inMethod&lt;span class="sym"&gt;){&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwc"&gt;StringBuilder&lt;/span&gt; javaFileContents &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;StringBuilder&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;outside &lt;span class="sym"&gt;+&lt;/span&gt;&lt;br /&gt;            &lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;public class TestClass{&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt;&lt;br /&gt;            inClass &lt;span class="sym"&gt;+&lt;/span&gt;&lt;br /&gt;            &lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;    &lt;span class="str"&gt;public void testMethod() throws Throwable {&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt;&lt;br /&gt;            inMethod &lt;span class="sym"&gt;+&lt;/span&gt;&lt;br /&gt;            &lt;span class="str"&gt;&amp;quot;try{this.getClass().getMethod(\&amp;quot;&lt;/span&gt;main\&lt;span class="str"&gt;&amp;quot;, String[].class).invoke(null, new Object[] {new String[]{}});} catch (NoSuchMethodException nsme) {}&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt;&lt;br /&gt;            &lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;}&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt;&lt;br /&gt;            &lt;span class="str"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;    JavaObjectFromString javaFileObject &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;try&lt;/span&gt;&lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        javaFileObject &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwd"&gt;JavaObjectFromString&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;TestClass&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; javaFileContents&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;toString&lt;/span&gt;&lt;span class="sym"&gt;());&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;span class="kwa"&gt;catch&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;Exception&lt;/span&gt; exception&lt;span class="sym"&gt;){&lt;/span&gt;&lt;br /&gt;        exception&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;printStackTrace&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;return&lt;/span&gt; javaFileObject&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now that we have the main infrastructure in place it is time for the action to unfold. This means creating the compiler object, a new task and invoking the task. I do not really want to parse the java fragments in the document to find where they belong, so I use a trick. I assume the fragment belongs either outside of the class I'm generating (import statements, other classes), in the class definition (fields, methods) or in the main method (instructions). I try to put each selection (you haven't forgotten that you can have multiple selections in OpenOffice, right?) in one of these three areas and invoke the task to see if it compiles without error. If it does, I go ahead with the next one:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;JavaCompiler compiler &lt;span class="sym"&gt;=&lt;/span&gt; ToolProvider&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getSystemJavaCompiler&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;JavaFileManager jfm &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwd"&gt;RAMFileManager&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;compiler&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;outside &lt;span class="sym"&gt;=&lt;/span&gt; inClass &lt;span class="sym"&gt;=&lt;/span&gt; inMethod &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;for&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;i&lt;span class="sym"&gt;=&lt;/span&gt;&lt;span class="num"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;i&lt;span class="sym"&gt;&amp;lt;&lt;/span&gt;count&lt;span class="sym"&gt;;&lt;/span&gt;i&lt;span class="sym"&gt;++) {&lt;/span&gt;&lt;br /&gt;    xTextRange &lt;span class="sym"&gt;= (&lt;/span&gt;XTextRange&lt;span class="sym"&gt;)&lt;/span&gt; UnoRuntime&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;queryInterface&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;XTextRange&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwa"&gt;class&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; xIndexAccess&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getByIndex&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;i&lt;span class="sym"&gt;));&lt;/span&gt;&lt;br /&gt;    newText &lt;span class="sym"&gt;=&lt;/span&gt; xTextRange&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getString&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    JavaFileObject javaObjectFromString &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwd"&gt;getJavaFileContentsAsString&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;outside &lt;span class="sym"&gt;+&lt;/span&gt; newText&lt;span class="sym"&gt;,&lt;/span&gt; inClass&lt;span class="sym"&gt;,&lt;/span&gt; inMethod&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwc"&gt;Iterable&lt;/span&gt; fileObjects &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;Arrays&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;asList&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Object&lt;/span&gt;&lt;span class="sym"&gt;[] {&lt;/span&gt;javaObjectFromString&lt;span class="sym"&gt;});&lt;/span&gt;&lt;br /&gt;    out &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;StringWriter&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;    CompilationTask task &lt;span class="sym"&gt;=&lt;/span&gt; compiler&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getTask&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;out&lt;span class="sym"&gt;,&lt;/span&gt; jfm&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; fileObjects&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwc"&gt;Boolean&lt;/span&gt; result &lt;span class="sym"&gt;=&lt;/span&gt; task&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;call&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;if&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;result&lt;span class="sym"&gt;){&lt;/span&gt;&lt;br /&gt;        outside &lt;span class="sym"&gt;+=&lt;/span&gt; newText&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt; &lt;span class="kwa"&gt;else&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        javaObjectFromString &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwd"&gt;getJavaFileContentsAsString&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;outside&lt;span class="sym"&gt;,&lt;/span&gt; inClass &lt;span class="sym"&gt;+&lt;/span&gt; newText&lt;span class="sym"&gt;,&lt;/span&gt; inMethod&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        fileObjects &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;Arrays&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;asList&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Object&lt;/span&gt;&lt;span class="sym"&gt;[] {&lt;/span&gt;javaObjectFromString&lt;span class="sym"&gt;});&lt;/span&gt;&lt;br /&gt;        task &lt;span class="sym"&gt;=&lt;/span&gt; compiler&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getTask&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;out&lt;span class="sym"&gt;,&lt;/span&gt; jfm&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; fileObjects&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        result &lt;span class="sym"&gt;=&lt;/span&gt; task&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;call&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;result&lt;span class="sym"&gt;){&lt;/span&gt;&lt;br /&gt;            inClass &lt;span class="sym"&gt;+=&lt;/span&gt; newText&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class="sym"&gt;}&lt;/span&gt; &lt;span class="kwa"&gt;else&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;            javaObjectFromString &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwd"&gt;getJavaFileContentsAsString&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;outside&lt;span class="sym"&gt;,&lt;/span&gt; inClass&lt;span class="sym"&gt;,&lt;/span&gt; inMethod &lt;span class="sym"&gt;+&lt;/span&gt; newText&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;            fileObjects &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;Arrays&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;asList&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Object&lt;/span&gt;&lt;span class="sym"&gt;[] {&lt;/span&gt;javaObjectFromString&lt;span class="sym"&gt;});&lt;/span&gt;&lt;br /&gt;            task &lt;span class="sym"&gt;=&lt;/span&gt; compiler&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getTask&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;out&lt;span class="sym"&gt;,&lt;/span&gt; jfm&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; fileObjects&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;            result &lt;span class="sym"&gt;=&lt;/span&gt; task&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;call&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;result&lt;span class="sym"&gt;){&lt;/span&gt;&lt;br /&gt;                inMethod &lt;span class="sym"&gt;+=&lt;/span&gt; newText&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span class="sym"&gt;}&lt;/span&gt; &lt;span class="kwa"&gt;else&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;                message &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Compilation fails:&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt; out&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;toString&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;                msgtype &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;errorbox&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;                title &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Compilation error&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;                &lt;span class="kwd"&gt;showMessage&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;                &lt;span class="kwa"&gt;return&lt;/span&gt; &lt;span class="num"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;At this stage, we already have compiled the class, but how to execute it? We need to define a class loader which knows specifically where to find and how to define the class (note the HashMap we used to store the classes):&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;ClassLoader&lt;/span&gt; cl &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;ClassLoader&lt;/span&gt;&lt;span class="sym"&gt;() {&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;protected&lt;/span&gt; &lt;span class="kwc"&gt;Class&lt;/span&gt; &lt;span class="kwd"&gt;findClass&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;String&lt;/span&gt; name&lt;span class="sym"&gt;)&lt;/span&gt; &lt;span class="kwa"&gt;throws&lt;/span&gt; &lt;span class="kwc"&gt;ClassNotFoundException&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        JavaFileObject jfo &lt;span class="sym"&gt;=&lt;/span&gt; output&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;get&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;name&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;jfo &lt;span class="sym"&gt;!=&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwb"&gt;byte&lt;/span&gt;&lt;span class="sym"&gt;[]&lt;/span&gt; bytes &lt;span class="sym"&gt;= ((&lt;/span&gt;RAMJavaFileObject&lt;span class="sym"&gt;)&lt;/span&gt; jfo&lt;span class="sym"&gt;).&lt;/span&gt;baos&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;toByteArray&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwa"&gt;return&lt;/span&gt; &lt;span class="kwd"&gt;defineClass&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;name&lt;span class="sym"&gt;,&lt;/span&gt; bytes&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="num"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; bytes&lt;span class="sym"&gt;.&lt;/span&gt;length&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwa"&gt;return super&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;findClass&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;name&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="sym"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now that we have the class, we can get the method and run it. Here I'm also doing some hocus-pocus in order to kidnap the standard output and show it in the message box- I am really interested in what actually is printed and if there are any exceptions:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwc"&gt;Class&lt;/span&gt; c &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;Class&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;forName&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;TestClass&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwb"&gt;true&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; cl&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;constructor &lt;span class="sym"&gt;=&lt;/span&gt; c&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getConstructor&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Class&lt;/span&gt;&lt;span class="sym"&gt;[]{});&lt;/span&gt;&lt;br /&gt;object &lt;span class="sym"&gt;=&lt;/span&gt; constructor&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;newInstance&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Object&lt;/span&gt;&lt;span class="sym"&gt;[]{});&lt;/span&gt;&lt;br /&gt;method &lt;span class="sym"&gt;=&lt;/span&gt; c&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getMethod&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;testMethod&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Class&lt;/span&gt;&lt;span class="sym"&gt;[]{});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;sysOut &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;System&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;out&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;sysErr &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;System&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;err&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// System.setOut(out);&lt;/span&gt;&lt;br /&gt;&lt;span class="kwc"&gt;PipedOutputStream&lt;/span&gt; pout &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;PipedOutputStream&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;span class="kwc"&gt;BufferedReader&lt;/span&gt; brout &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;BufferedReader&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;InputStreamReader&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;PipedInputStream&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;pout&lt;span class="sym"&gt;)));&lt;/span&gt;&lt;br /&gt;&lt;span class="kwc"&gt;System&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;setOut&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;PrintStream&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;pout&lt;span class="sym"&gt;));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwc"&gt;PipedOutputStream&lt;/span&gt; perr &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;PipedOutputStream&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;span class="kwc"&gt;BufferedReader&lt;/span&gt; brerr &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;BufferedReader&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;InputStreamReader&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;PipedInputStream&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;perr&lt;span class="sym"&gt;)));&lt;/span&gt;&lt;br /&gt;&lt;span class="kwc"&gt;System&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;setErr&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;PrintStream&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;perr&lt;span class="sym"&gt;));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;message &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Compiled and ran successfully:&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;msgtype &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;infobox&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;title &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Success&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;try&lt;/span&gt; &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;    method&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;invoke&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;object&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;Object&lt;/span&gt;&lt;span class="sym"&gt;[]{});&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt; &lt;span class="kwa"&gt;catch&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;Throwable&lt;/span&gt; t&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;    message &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Runtime error:&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;+&lt;/span&gt; t&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    msgtype &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;errorbox&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    title &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Runtime error&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;sb &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;StringBuilder&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;while&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;brout&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;ready&lt;/span&gt;&lt;span class="sym"&gt;()) {&lt;/span&gt;&lt;br /&gt;    sb&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;append&lt;/span&gt;&lt;span class="sym"&gt;((&lt;/span&gt;&lt;span class="kwb"&gt;char&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; brout&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;read&lt;/span&gt;&lt;span class="sym"&gt;());&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;message &lt;span class="sym"&gt;+= (&lt;/span&gt;sb&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;length&lt;/span&gt;&lt;span class="sym"&gt;() ==&lt;/span&gt; &lt;span class="num"&gt;0&lt;/span&gt; ? &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;Output:&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;) +&lt;/span&gt; sb&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;toString&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;sb &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwc"&gt;StringBuilder&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;while&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;brerr&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;ready&lt;/span&gt;&lt;span class="sym"&gt;()) {&lt;/span&gt;&lt;br /&gt;    sb&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;append&lt;/span&gt;&lt;span class="sym"&gt;((&lt;/span&gt;&lt;span class="kwb"&gt;char&lt;/span&gt;&lt;span class="sym"&gt;)&lt;/span&gt; brerr&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;read&lt;/span&gt;&lt;span class="sym"&gt;());&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;message &lt;span class="sym"&gt;+= (&lt;/span&gt;sb&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;length&lt;/span&gt;&lt;span class="sym"&gt;() ==&lt;/span&gt; &lt;span class="num"&gt;0&lt;/span&gt; ? &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;Error:&lt;/span&gt;&lt;span class="esc"&gt;\n&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;) +&lt;/span&gt; sb&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;toString&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwc"&gt;System&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;setOut&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;sysOut&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class="kwc"&gt;System&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;setErr&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;sysErr&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwd"&gt;showMessage&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that's it! What's that you ask? We don't know anything about the showMessage method? You're really curious, aren't you? OK, here it is, mostly taken from the OpenOffice UNO interface:&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="kwd"&gt;showMessage&lt;/span&gt;&lt;span class="sym"&gt;() {&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;import&lt;/span&gt; com&lt;span class="sym"&gt;.&lt;/span&gt;sun&lt;span class="sym"&gt;.&lt;/span&gt;star&lt;span class="sym"&gt;.&lt;/span&gt;awt&lt;span class="sym"&gt;.&lt;/span&gt;XToolkit&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;import&lt;/span&gt; com&lt;span class="sym"&gt;.&lt;/span&gt;sun&lt;span class="sym"&gt;.&lt;/span&gt;star&lt;span class="sym"&gt;.&lt;/span&gt;awt&lt;span class="sym"&gt;.&lt;/span&gt;XMessageBoxFactory&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;import&lt;/span&gt; com&lt;span class="sym"&gt;.&lt;/span&gt;sun&lt;span class="sym"&gt;.&lt;/span&gt;star&lt;span class="sym"&gt;.&lt;/span&gt;awt&lt;span class="sym"&gt;.&lt;/span&gt;XMessageBox&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;import&lt;/span&gt; com&lt;span class="sym"&gt;.&lt;/span&gt;sun&lt;span class="sym"&gt;.&lt;/span&gt;star&lt;span class="sym"&gt;.&lt;/span&gt;awt&lt;span class="sym"&gt;.&lt;/span&gt;XWindowPeer&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    m_xContext &lt;span class="sym"&gt;=&lt;/span&gt; XSCRIPTCONTEXT&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getComponentContext&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;    m_xMCF &lt;span class="sym"&gt;=&lt;/span&gt; m_xContext&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getServiceManager&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwc"&gt;Object&lt;/span&gt; oToolkit &lt;span class="sym"&gt;=&lt;/span&gt; m_xMCF&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;createInstanceWithContext&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;com.sun.star.awt.Toolkit&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; m_xContext&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;    XToolkit xToolkit &lt;span class="sym"&gt;= (&lt;/span&gt;XToolkit&lt;span class="sym"&gt;)&lt;/span&gt; UnoRuntime&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;queryInterface&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;XToolkit&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwa"&gt;class&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; oToolkit&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    windowPeer &lt;span class="sym"&gt;=&lt;/span&gt; xTextDoc&lt;span class="sym"&gt;.&lt;/span&gt;currentController&lt;span class="sym"&gt;.&lt;/span&gt;frame&lt;span class="sym"&gt;.&lt;/span&gt;containerWindow&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;    XWindowPeer xWindowPeer &lt;span class="sym"&gt;= (&lt;/span&gt;XWindowPeer&lt;span class="sym"&gt;)&lt;/span&gt; UnoRuntime&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;queryInterface&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;XWindowPeer&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwa"&gt;class&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; windowPeer&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    com&lt;span class="sym"&gt;.&lt;/span&gt;sun&lt;span class="sym"&gt;.&lt;/span&gt;star&lt;span class="sym"&gt;.&lt;/span&gt;awt&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;Rectangle&lt;/span&gt; aRectangle &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; com&lt;span class="sym"&gt;.&lt;/span&gt;sun&lt;span class="sym"&gt;.&lt;/span&gt;star&lt;span class="sym"&gt;.&lt;/span&gt;awt&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;Rectangle&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    XMessageBoxFactory xMessageBoxFactory &lt;span class="sym"&gt;= (&lt;/span&gt;XMessageBoxFactory&lt;span class="sym"&gt;)&lt;/span&gt; UnoRuntime&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;queryInterface&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;XMessageBoxFactory&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwa"&gt;class&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; oToolkit&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;    XMessageBox xMessageBox &lt;span class="sym"&gt;=&lt;/span&gt; xMessageBoxFactory&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;createMessageBox&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;xWindowPeer&lt;span class="sym"&gt;,&lt;/span&gt; aRectangle&lt;span class="sym"&gt;,&lt;/span&gt; msgtype&lt;span class="sym"&gt;,&lt;/span&gt; com&lt;span class="sym"&gt;.&lt;/span&gt;sun&lt;span class="sym"&gt;.&lt;/span&gt;star&lt;span class="sym"&gt;.&lt;/span&gt;awt&lt;span class="sym"&gt;.&lt;/span&gt;MessageBoxButtons&lt;span class="sym"&gt;.&lt;/span&gt;BUTTONS_OK&lt;span class="sym"&gt;,&lt;/span&gt; title&lt;span class="sym"&gt;,&lt;/span&gt; message&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;xMessageBox &lt;span class="sym"&gt;!=&lt;/span&gt; &lt;span class="kwb"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;){&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwb"&gt;short&lt;/span&gt; nResult &lt;span class="sym"&gt;=&lt;/span&gt; xMessageBox&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;execute&lt;/span&gt;&lt;span class="sym"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What's missing is a couple of import statements and standard initializing lines found in every OpenOffice macro template, but this blog post is already too long. And it's better that you ask if you need it rather than get bored and not even get to the end.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-469794096328381406?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/469794096328381406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=469794096328381406' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/469794096328381406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/469794096328381406'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/04/instant-evaluation-of-java-code-in.html' title='Instant evaluation of Java code in OpenOffice'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-4068004490353567827</id><published>2008-04-02T12:53:00.020+03:00</published><updated>2008-04-11T10:36:59.963+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Playing with Javascript or what binds Greasemonkey, Twitter and Ambient Avatars together</title><content type='html'>It's been a while since I tried JavaScript hacking (almost 2 years). This time I had the haunting idea to create a &lt;a href="http://www.greasespot.net/"&gt;Greasemonkey&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Mashup_(web_application_hybrid)"&gt;mashup&lt;/a&gt; so I can see my twitter page with the avatar next to each tweet exactly as it looked at the time the tweet was posted.&lt;br /&gt;&lt;br /&gt;To do this the avatar history must be stored somewhere. That's where &lt;a href="http://www.chinposin.com"&gt;chinposin.com&lt;/a&gt; comes in. Initially originated as a refreshing avatar on Friday, it evolved into the Ambient Avatar Platform (TM) (credit goes to @&lt;a href="http://twitter.com/monkchips"&gt;monkchips&lt;/a&gt; and @&lt;a href="http://twitter.com/yellowpark"&gt;yellowpark&lt;/a&gt;- you're great). In simple words- you follow @&lt;a href="http://twitter.com/chinposin"&gt;chinposin&lt;/a&gt; on twitter, and when you change your avatar, the old one is saved. So you have a gallery of all of your previous avatars for your previewing pleasure and along with the dates they were changed.&lt;br /&gt;&lt;br /&gt;For those of you wondering what's twitter, that's a topic for an entire new blog post... or a whole blog, so start at &lt;a href="http://en.wikipedia.org/wiki/Twitter"&gt;wikipedia&lt;/a&gt;, so we can continue with the interesting stuff, shall we?&lt;br /&gt;&lt;br /&gt;So there we are- we want to include info from one site into another- a task where Greasemonkey excels (normally JavaScript cannot just fetch info from any other site at whim).&lt;br /&gt;&lt;br /&gt;I've obviously lost some of my JavaScript knowledge since it took me an obscene amount of time to get this tiny piece of code working. To start off, I had forgotten that Greasemonkey had also some restrictions, not only enhancements. For security purposes, a lot of objects were wrapped in &lt;a href="http://developer.mozilla.org/en/docs/XPCNativeWrapper"&gt;XPCNativeWrapper&lt;/a&gt; and I had to use loads of &lt;a href="http://www.oreillynet.com/pub/a/network/2005/11/01/avoid-common-greasemonkey-pitfalls.html?page=5"&gt;wrappedJSObject&lt;/a&gt; as a workaround. Yes, I know it's not secure, and you should know this too.&lt;br /&gt;&lt;br /&gt;Another issue I had a problem with was passing an argument to a closure. I eventually remembered that the closure is an object and you can just assign any field to an object, because each object is also an associative array. Accessing the function object from itself also took some googling- &lt;code&gt;arguments.callee&lt;/code&gt; did the trick.&lt;br /&gt;&lt;br /&gt;So is there anything that can be improved in this shoddy script? You bet. For starters, it loads the chinposin site a lot, sending 20 simultaneous requests right off the bat, even for duplicate user pages. I could cache the avatar history, but that would require that I synchronize the requests. This script could be modified into a Firefox extension, which has less restrictions than Greasemonkey. And I really should use a prototype for those twenty closures I create, but I gotta have something to do for next time, right?&lt;br /&gt;&lt;br /&gt;Without further ado, here's the script. Copy it and paste it into twitteravatarhistory.user.js (OK, you can come up with a longer name if you're so inclined). Then open it with Firefox and if Greasemonkey is installed you will be presented with a dialog prompting you to install it. It's tested with Firefox 2.0.0.13, 3a9, 3b4 and Greasemonkey 0.6.6.20061017 and 0.7.20080121.0. Considering the rate of change, I would be surprised it works in 1 year.&lt;br /&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="slc"&gt;// ==UserScript==&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// &amp;#64;name          TwitterAvatarHistory&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// &amp;#64;description   Shows tweets with the avatar at time of posting&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// &amp;#64;include       http://twitter.com/*&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// ==/UserScript==&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="slc"&gt;// Assumptions:&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// -chinposin.com has a special date string under the pic&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// -avatars are listed chronologically&lt;/span&gt;&lt;br /&gt;&lt;span class="slc"&gt;// -many others regarding DOM position&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwa"&gt;const&lt;/span&gt; avatar_home &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;http://www.chinposin.com/home/&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;var&lt;/span&gt; twitter_images &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;document&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;evaluate&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'//.[contains(&amp;#64;class, &amp;quot;hentry&amp;quot;)]'&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;document&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwa"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; XPathResult&lt;span class="sym"&gt;.&lt;/span&gt;UNORDERED_NODE_ITERATOR_TYPE&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwa"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class="kwa"&gt;while&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;message &lt;span class="sym"&gt;=&lt;/span&gt; twitter_images&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;iterateNext&lt;/span&gt;&lt;span class="sym"&gt;()) {&lt;/span&gt;&lt;br /&gt; message &lt;span class="sym"&gt;=&lt;/span&gt; message&lt;span class="sym"&gt;.&lt;/span&gt;wrappedJSObject&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="slc"&gt;// Read user name&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;var&lt;/span&gt; url &lt;span class="sym"&gt;=&lt;/span&gt; message&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)[&lt;/span&gt;&lt;span class="num"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;];&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(!&lt;/span&gt;url&lt;span class="sym"&gt;)&lt;/span&gt; &lt;span class="kwa"&gt;continue&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;var&lt;/span&gt; username &lt;span class="sym"&gt;=&lt;/span&gt; url&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getAttribute&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;href&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;&lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;[^/]*$&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="slc"&gt;// Read date of message and extract fields with a regexp&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;var&lt;/span&gt; date_string &lt;span class="sym"&gt;=&lt;/span&gt; message&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;published&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)[&lt;/span&gt;&lt;span class="num"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;].&lt;/span&gt;&lt;span class="kwd"&gt;getAttribute&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;var&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt; &lt;span class="sym"&gt;=&lt;/span&gt; date_string&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;(/(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;4&lt;/span&gt;&lt;span class="sym"&gt;})-(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;})-(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;})&lt;/span&gt;&lt;span class="kwd"&gt;T&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;}):(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;}):(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;})&lt;/span&gt;\+&lt;span class="sym"&gt;(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;}):(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;})/);&lt;/span&gt;&lt;br /&gt; &lt;span class="kwa"&gt;var&lt;/span&gt; date &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwd"&gt;Date&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;3&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;4&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;5&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;6&lt;/span&gt;&lt;span class="sym"&gt;]);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="kwa"&gt;var&lt;/span&gt; http &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;function&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;responseDetails&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;  &lt;span class="slc"&gt;// add dummy element so we can operate on its DOM&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;var&lt;/span&gt; elem &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;document&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;createElement&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;html&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwc"&gt;document&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;body&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;appendChild&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;elem&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;  elem&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;innerHTML&lt;/span&gt; &lt;span class="sym"&gt;=&lt;/span&gt; responseDetails&lt;span class="sym"&gt;.&lt;/span&gt;responseText&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="slc"&gt;// getElementById is only found in document object, will use XPath&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;var&lt;/span&gt; gallery &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwc"&gt;document&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;evaluate&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'//.[&amp;#64;id=&amp;quot;gallery&amp;quot;]'&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; elem&lt;span class="sym"&gt;.&lt;/span&gt;wrappedJSObject&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwa"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt;&lt;br /&gt;                       XPathResult&lt;span class="sym"&gt;.&lt;/span&gt;ANY_UNORDERED_NODE_TYPE&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwa"&gt;null&lt;/span&gt;&lt;span class="sym"&gt;).&lt;/span&gt;singleNodeValue&lt;span class="sym"&gt;.&lt;/span&gt;wrappedJSObject&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="slc"&gt;// Might be better to couple these more tightly than creating two separate arrays&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;var&lt;/span&gt; &lt;span class="kwc"&gt;images&lt;/span&gt; &lt;span class="sym"&gt;=&lt;/span&gt; gallery&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;img&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;var&lt;/span&gt; dates &lt;span class="sym"&gt;=&lt;/span&gt; gallery&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;mainText&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="slc"&gt;// Find avatar date not more recent than message date&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwa"&gt;for&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;i &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="num"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt; i &lt;span class="sym"&gt;&amp;lt;&lt;/span&gt; dates&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;length&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt; i&lt;span class="sym"&gt;++) {&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwa"&gt;var&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt; &lt;span class="sym"&gt;=&lt;/span&gt; dates&lt;span class="sym"&gt;[&lt;/span&gt;i&lt;span class="sym"&gt;].&lt;/span&gt;textContent&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;(/(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;4&lt;/span&gt;&lt;span class="sym"&gt;})-(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;})-(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;}) +(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;}):(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;}):(&lt;/span&gt;\d&lt;span class="sym"&gt;{&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;})/);&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwa"&gt;var&lt;/span&gt; avatar_date &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span class="kwa"&gt;new&lt;/span&gt; &lt;span class="kwd"&gt;Date&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;2&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;3&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;4&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;5&lt;/span&gt;&lt;span class="sym"&gt;],&lt;/span&gt; &lt;span class="kwc"&gt;match&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;&lt;span class="num"&gt;6&lt;/span&gt;&lt;span class="sym"&gt;]);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span class="kwa"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;avatar_date &lt;span class="sym"&gt;&amp;lt;&lt;/span&gt; arguments&lt;span class="sym"&gt;.&lt;/span&gt;callee&lt;span class="sym"&gt;.&lt;/span&gt;date&lt;span class="sym"&gt;) {&lt;/span&gt;&lt;br /&gt;    &lt;span class="slc"&gt;// Replace message pic with avatar corresponding to date&lt;/span&gt;&lt;br /&gt;    arguments&lt;span class="sym"&gt;.&lt;/span&gt;callee&lt;span class="sym"&gt;.&lt;/span&gt;img&lt;span class="sym"&gt;.&lt;/span&gt;firstChild&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;setAttribute&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;src&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;images&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;i&lt;span class="sym"&gt;].&lt;/span&gt;&lt;span class="kwd"&gt;getAttribute&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;src&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;))&lt;/span&gt;&lt;br /&gt;    &lt;span class="slc"&gt;// TMTOWTDI:&lt;/span&gt;&lt;br /&gt;    &lt;span class="slc"&gt;//~ arguments.callee.img.replaceChild(images[i].cloneNode(false), arguments.callee.img.firstChild);&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwa"&gt;break&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="slc"&gt;// clean up temp structure&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwc"&gt;document&lt;/span&gt;&lt;span class="sym"&gt;.&lt;/span&gt;body&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;removeChild&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;elem&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="slc"&gt;// Trick to pass data to the closure&lt;/span&gt;&lt;br /&gt; http&lt;span class="sym"&gt;.&lt;/span&gt;date &lt;span class="sym"&gt;=&lt;/span&gt; date&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt; http&lt;span class="sym"&gt;.&lt;/span&gt;img &lt;span class="sym"&gt;=&lt;/span&gt; message&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;)[&lt;/span&gt;&lt;span class="num"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;];&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="slc"&gt;// Reach list of pix from user page&lt;/span&gt;&lt;br /&gt; &lt;span class="kwd"&gt;GM_xmlhttpRequest&lt;/span&gt;&lt;span class="sym"&gt;({&lt;/span&gt;&lt;span class="kwc"&gt;method&lt;/span&gt; &lt;span class="sym"&gt;:&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;&lt;span class="sym"&gt;,&lt;/span&gt; url &lt;span class="sym"&gt;:&lt;/span&gt; avatar_home &lt;span class="sym"&gt;+&lt;/span&gt; username&lt;span class="sym"&gt;,&lt;/span&gt; &lt;span class="kwc"&gt;onload&lt;/span&gt; &lt;span class="sym"&gt;:&lt;/span&gt; http&lt;span class="sym"&gt;});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Update: code formatting had munched some of the Greasemonkey header, that should be fixed now.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Update 10 April 2008: New code's on &lt;a href="http://userscripts.org/scripts/show/24798"&gt;Greasemonkey repository&lt;/a&gt; since last week, today a fix was issued that adapts to twitter interface changes.&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-4068004490353567827?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/4068004490353567827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=4068004490353567827' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/4068004490353567827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/4068004490353567827'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/04/its-been-while-since-i-tried-javascript.html' title='Playing with Javascript or what binds Greasemonkey, Twitter and Ambient Avatars together'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7206939994948735545.post-6714938491397330273</id><published>2008-03-20T18:53:00.006+02:00</published><updated>2008-03-25T14:31:22.547+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='languages'/><title type='text'>A New Year's resolution</title><content type='html'>The start of each year invariably makes us look back and wish to bring more purpose to the next year. So did I have an improved New Year's Resolution? Of course- &lt;a href="http://lifehacker.com/336991/free-tools-to-manage-new-years-resolutions#c3505925"&gt;1280x1024&lt;/a&gt;. A bit more significant, though, was to find another programming language to learn this year (following the sound advice from "Pragmatic" Dave Thomas).&lt;br /&gt;&lt;br /&gt;Since we geeks can sometimes be programming language junkies, this was harder for me to do than previous years. I've previously improved my knowledge about &lt;a href="http://perldoc.perl.org/"&gt;Perl&lt;/a&gt;(2004), &lt;a href="http://www.diveintopython.org/"&gt;Python&lt;/a&gt; (2005), &lt;a href="http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html"&gt;Tcl&lt;/a&gt; (2006) and &lt;a href="http://rubycentral.com/book/"&gt;Ruby&lt;/a&gt; (2007). They served their purpose but this year I felt it's about time to depart a bit from my comfort zone and try a new concept. As &lt;a href="http://norvig.com/21-days.html"&gt;someone with much more experience&lt;/a&gt; noted, "A language that doesn't affect the way you think about programming, is not worth knowing".&lt;br /&gt;&lt;br /&gt;So I did my homework and did a bit of &lt;a href="http://steve.yegge.googlepages.com/language-grubbing"&gt;research&lt;/a&gt; and nominated the following languages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Scheme&lt;/span&gt;: yes I've done some functional programming in the university and I've edited an Emacs Lisp macro or two, but if you're not using it, you're losing it. Besides, I've always wanted (and postponed forever) reading "The Little Schemer", which has an almost cult status.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Logo&lt;/span&gt;: This elegant language is sometimes referred to as "LISP without the parentheses". I did some research about which programming language I should start teaching my son first (yeah I know it's ridiculously early to do that before your son is even born!) and decided that LOGO is the all-time favorite kids' programming language. Of course, being famous for its graph-drawing turtle does not mean it can't be used as a serious language. Anyway, it would be a pity if I don't learn it some day, given my relatives with some years of research on Logo.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Haskell&lt;/span&gt;: One of the most exotic in this mix, Haskell's lazy evaluation and monads sound novel enough to be fun to learn, besides it's getting some moderate popularity and there is even real-world software written in Haskell, like the Perl 6 compiler/interpreter and revision-control system Darcs (OK, Perl 6 is not a real-world software yet).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Erlang&lt;/span&gt;: One of the promises of Erlang is that it can deliver one of the easiest concurrency programming models with  message passing between lightweight processes. Besides, it seems to be a fairly simple (compared to Haskell at least) functional language, while still preserving power features like pattern matching. Last, but not least, I really like hot class (module?) reloading and compared to the hot swap feature in the JVM it is really much more pervasive, so much easier for debugging, monitoring, quick fixes, etc.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Scala&lt;/span&gt;: It's not just object-oriented and it's not just functional, because it's a language with many influences- it even has pattern matching and Erlang's message passing model for concurrency. One of the best advantages is that it works on the JVM and integrates seamlessly with existing Java libraries.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Groovy&lt;/span&gt;: This is another promising dynamic language on the JVM, which seems to draw a lot of its influence from Ruby, including a Rails-like webapp framework, called Grails (surprising choice of name, huh?). Since my professional work is related to Java, I might learn this sooner or later because I think we would be seeing more from this (we already are). Especially for working with XML builders seem to be making things much smoother.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Interestingly, along with my new big-resolution display came a dual-core processor. Everyone knows that multiple cores will be all over the place soon. So my curiosity about how you can  make these multiple processors scale based on the programming language model itself, took over. That leaves Erlang and Scala.&lt;br /&gt;&lt;br /&gt;Of course that's not all of it. Logo's time just hadn't come yet, as my son is too young for me to start seriously teaching him (hell, he doesn't even know a human language to start with). Groovy could wait as well and it shouldn't be hard at all to pick up with Python, Ruby and Java behind my back. Erlang might be an easier first step into serious functional programming than Haskell and Scheme... well I guess I can postpone it for one more year and make do with Emacs Lisp.&lt;br /&gt;&lt;br /&gt;But which one should it be- Erlang or Scala? Erlang is recommended by the same Pragmatic Dave who is responsible for me learning Ruby. And Scala's creator, Martin Odersky, is the man behind Java Generics and the current Java compiler.&lt;br /&gt;&lt;br /&gt;But you know what? I didn't have to decide (or I might have learned none of these). My brother has the uncanny ability to guess what I want for a present, so he got me &lt;a href="http://www.pragprog.com/titles/jaerlang"&gt;Programming Erlang&lt;/a&gt; from the Pragmatic bookshelf. And my father has the great ability to ask me what I want for a present, so he got me the &lt;a href="http://www.artima.com/shop/forsale"&gt;Programming in Scala&lt;/a&gt; from Artima.&lt;br /&gt;&lt;br /&gt;Eventually, I must have done a fairly good job on my language research because my list was not very different from the one in &lt;a href="http://dobbscodetalk.com/index.php?option=com_myblog&amp;amp;show=Learn-as-Many-Languages-as-You-Can-or-just-learn-Scala-.html&amp;amp;Itemid=29"&gt;an article about new languages on Dr.Dobb's Journal&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;On a side note- ordering PDF books is great- you can search easily, you don't destroy trees and you get the updates of new revisions easily- go for it!&lt;br /&gt;&lt;br /&gt;So there I am, with two languages instead of one for this year, although Erlang and Scala have a lot in common. With the surge of interest in new programming languages one language per year only might take me forever to cover all I wanted to learn.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7206939994948735545-6714938491397330273?l=speaking-my-language.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://speaking-my-language.blogspot.com/feeds/6714938491397330273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7206939994948735545&amp;postID=6714938491397330273' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/6714938491397330273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7206939994948735545/posts/default/6714938491397330273'/><link rel='alternate' type='text/html' href='http://speaking-my-language.blogspot.com/2008/03/new-years-resolution.html' title='A New Year&apos;s resolution'/><author><name>Vassil Dichev</name><uri>http://www.blogger.com/profile/14522675986593535178</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
