<?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-6818189468244276547</id><updated>2011-08-02T22:38:27.400-07:00</updated><category term='scala'/><title type='text'>Quoi qu'il en soit</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-3664583285902414830</id><published>2011-03-23T05:13:00.000-07:00</published><updated>2011-03-23T05:13:16.705-07:00</updated><title type='text'>An example of why C# kicks Java's butt: Fluent NHibernate</title><content type='html'>&lt;div class="MsoNormal"&gt;&lt;a href="http://stackoverflow.com/questions/1592575/does-fluent-hibernate-exist"&gt;http://stackoverflow.com/questions/1592575/does-fluent-hibernate-exist&lt;/a&gt;&lt;span class="comment-copy"&gt;&lt;span style="border: none windowtext 1.0pt; color: #444444; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt; mso-border-alt: none windowtext 0cm; padding: 0cm;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span class="comment-copy"&gt;&lt;span style="border: none windowtext 1.0pt; color: #444444; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt; mso-border-alt: none windowtext 0cm; padding: 0cm;"&gt;“From the horses mouth (I'm the lead developer on Fluent NHibernate): the reason Fluent Hibernate doesn't exist is exactly because of the lack of lambda expressions [in Java]. It's not just the lack of basic lambdas, but the ability to parse those expressions that FNH relies heavily on; without which you'd need to resort to strings and that's no better than XML in my opinion. It's always a possibility for the future though.&lt;/span&gt;&lt;/span&gt;&lt;span class="apple-converted-space"&gt;&lt;span style="color: #444444; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="apple-style-span"&gt;&lt;span style="color: #444444; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;–&amp;nbsp;&lt;a href="http://stackoverflow.com/users/27206/james-gregory" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-color: initial; border-style: initial; cursor: pointer;" title="5964 reputation"&gt;&lt;span style="border: none windowtext 1.0pt; color: #0077cc; mso-border-alt: none windowtext 0cm; padding: 0cm;"&gt;James Gregory&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="apple-converted-space"&gt;&lt;span style="color: #444444; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt;"&gt;&amp;nbsp;&lt;span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-color: initial; border-style: initial;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="comment-date"&gt;&lt;span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-color: initial; border-style: initial;" title="2009-10-22 09:08:40Z"&gt;&lt;span style="border: none windowtext 1.0pt; color: #999999; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 10.0pt; mso-border-alt: none windowtext 0cm; padding: 0cm;"&gt;Oct 22 '09 at 9:08&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;”&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-3664583285902414830?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/3664583285902414830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=3664583285902414830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3664583285902414830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3664583285902414830'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2011/03/example-of-why-c-kicks-javas-butt.html' title='An example of why C# kicks Java&apos;s butt: Fluent NHibernate'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-5927187612521628927</id><published>2010-06-28T05:56:00.000-07:00</published><updated>2010-07-25T04:42:07.445-07:00</updated><title type='text'>Release port 8080 after tomcat crash on windows 7</title><content type='html'>&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Check which process is using port 80&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;On the command prompt window, type the following command.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;netstat -o -n -a | findstr 0.0:8080&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;C:\dev&amp;gt;netstat -o -n -a | findstr 0.0:8080&lt;br /&gt;&amp;nbsp; TCP&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.0.0.0:8080&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.0.0.0:0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LISTENING&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6352&lt;/span&gt; &lt;/div&gt;&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"&gt;&lt;span class="Apple-style-span" style="color: #4e4e4e;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"&gt;&lt;span class="Apple-style-span" style="color: #4e4e4e;"&gt;&lt;div style="line-height: 19px; margin: 0px 0px 0.8em; padding: 0px; text-align: justify;"&gt;&lt;strong style="margin: 0px; padding: 0px;"&gt;Open&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;a class="zem_slink" href="http://en.wikipedia.org/wiki/Windows_Task_Manager" rel="wikipedia" style="color: #0071bb; margin: 0px; outline-style: none; padding: 0px;" title="Windows Task Manager"&gt;Task Manager&lt;/a&gt;&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;to check the process ID&lt;/strong&gt;&lt;/div&gt;&lt;ol style="line-height: 19px; margin: 0.4em 0px 1em; padding: 0px; text-align: justify;"&gt;&lt;li style="list-style-position: outside; margin: 0px 0px 0px 2.5em; padding: 0px;"&gt;Right click on the taskbar to open the the&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;strong style="margin: 0px; padding: 0px;"&gt;task manager&lt;/strong&gt;.&lt;/li&gt;&lt;li style="list-style-position: outside; margin: 0px 0px 0px 2.5em; padding: 0px;"&gt;Go to the&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;strong style="margin: 0px; padding: 0px;"&gt;Processes&lt;/strong&gt;&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;tab.&lt;/li&gt;&lt;li style="list-style-position: outside; margin: 0px 0px 0px 2.5em; padding: 0px;"&gt;Click the&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;strong style="margin: 0px; padding: 0px;"&gt;View&lt;/strong&gt;&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;menu&lt;/li&gt;&lt;li style="list-style-position: outside; margin: 0px 0px 0px 2.5em; padding: 0px;"&gt;And make sure you select the&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;strong style="margin: 0px; padding: 0px;"&gt;PID (Process Identifier)&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"&gt;&lt;span class="Apple-style-span" style="color: #4e4e4e;"&gt;&lt;strong style="margin: 0px; padding: 0px;"&gt;Find the process and kill it&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-5927187612521628927?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/5927187612521628927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/5927187612521628927'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2010/06/release-port-8080-after-tomcat-crash-on.html' title='Release port 8080 after tomcat crash on windows 7'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-740213470520808241</id><published>2010-04-27T06:29:00.001-07:00</published><updated>2010-04-27T06:30:31.048-07:00</updated><title type='text'>Oracle: convert a varchar2 to a CLOB without dropping the table</title><content type='html'>Current defn of column in table NOTIFICATION&lt;br /&gt;&lt;br /&gt;DETAIL    VARCHAR2(4000),&lt;br /&gt;&lt;br /&gt;Want it to be a CLOB. &lt;br /&gt;&lt;br /&gt;create a temporary table 'NOTIFICATION2' with the required column defintions. This is then used as a template to convert the table column. &lt;br /&gt;&lt;br /&gt;exec dbms_redefinition.start_redef_table('TSUSER','NOTIFICATION','NOTIFICATION2','ID, RECIPIENT, SUBJECT, TO_CLOB(DETAIL) DETAIL, FOOTER, ISSUE_DATE, SENT_DATE, SENT_STATUS, RETRY_COUNT, ROLE',dbms_redefinition.cons_use_pk);&lt;br /&gt;exec dbms_redefinition.finish_redef_table('TSUSER','NOTIFICATION','NOTIFICATION2');&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-740213470520808241?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/740213470520808241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=740213470520808241' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/740213470520808241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/740213470520808241'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2010/04/oracle-convert-varchar2-to-clob-without.html' title='Oracle: convert a varchar2 to a CLOB without dropping the table'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-8277516002081143785</id><published>2010-04-15T06:20:00.000-07:00</published><updated>2010-04-15T06:49:57.235-07:00</updated><title type='text'>Scala asymmetrical function definitions</title><content type='html'>I was impressed by the clarity of the &lt;a href="http://c2.com/cgi/wiki?OddWordProblemSolutions"&gt;"Better Haskell solution"&lt;/a&gt; to this &lt;a href="http://c2.com/cgi/wiki?OddWordProblem"&gt;Odd Word problem&lt;/a&gt;. (Disclaimer: I don't know haskell, but I can just about read a simple example like the one in this problem.)&lt;br /&gt;&lt;br /&gt;haskell:&lt;br /&gt;&lt;pre class="brush: plain"&gt;import Data.List&lt;br /&gt;&lt;br /&gt; enumerate = zip $ cycle [0,1]&lt;br /&gt;&lt;br /&gt; oddwords x = foldl' add "" (enumerate ws) ++ "."&lt;br /&gt;     where add "" (_,t) = t&lt;br /&gt;           add s (0, t) = s ++ " " ++ t&lt;br /&gt;           add s (1, t) = s ++ " " ++ reverse t&lt;br /&gt;           ws = words $ takeWhile (/= '.') x&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So I added a Scala version that is a translation of the Haskell which I'm repeating here which copies the essence of the Haskell algorithm as well as the names used: &lt;br /&gt;&lt;pre class="brush: scala"&gt;object OddWordProblem1 {&lt;br /&gt;  &lt;br /&gt;    // define cycle as per Haskell as Scala does not define it &lt;br /&gt;    def cycle[T](seq: Seq[T]) = Stream.continually(seq).flatten&lt;br /&gt;&lt;br /&gt;    def enumerate[T](words: Seq[T]) = cycle(List(0,1)) zip words   &lt;br /&gt;    &lt;br /&gt;    def oddwords(input : String) = {&lt;br /&gt;        &lt;br /&gt;        def add(stringSoFar : String, wordAndOddIndicator : (Int,String)) = &lt;br /&gt;            (stringSoFar, wordAndOddIndicator) match {&lt;br /&gt;                case ("", (_, t)) =&gt; t&lt;br /&gt;                case (s, (0, t)) =&gt; s + " " + t&lt;br /&gt;                case (s, (1, t)) =&gt; s + " " + t.reverse&lt;br /&gt;            }&lt;br /&gt;        &lt;br /&gt;        def ws(words : Seq[String]) = words takeWhile ("." !=)&lt;br /&gt;        &lt;br /&gt;        // split the string into words,  first making sure that "kansas." always becomes "kansas ."&lt;br /&gt;        val words =  input.replaceFirst("""\.""", " .").split(" +").toList&lt;br /&gt;        &lt;br /&gt;        enumerate(ws(words)).foldLeft("")(add) + "."&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    def main(args : Array[String]) = {&lt;br /&gt;        println(oddwords("whats the matter with kansas."))&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The core logic is a bit longer than the Haskell version because &lt;br /&gt;(a) Its doing IO(!) and handling input corner cases and is self contained and runnable.&lt;br /&gt;(b) It defines cycle which is no big deal&lt;br /&gt;(c) It defines method parameters and their types&lt;br /&gt;(d) It has more brackets than haskell as haskell does not use brackets for function application. Not much we can do about that.&lt;br /&gt;&lt;br /&gt;So, we have to define method parameters and their types, or do we? Now it could be argued that defining the parameters and types is good for readability, but it would be nice to have the choice. But of course with inline anonymous functions, the parameters and types are not required. So instead of defining the add method separately, we can write, &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;def oddwords(input : String) = {&lt;br /&gt;&lt;br /&gt;  def ws(words : Seq[String]) = words takeWhile ("." !=)&lt;br /&gt;&lt;br /&gt;  val words =  input.replaceFirst("""\.""", " .").split(" +").toList&lt;br /&gt;&lt;br /&gt;  enumerate(ws(words)).foldLeft(""){&lt;br /&gt;    (_, _) match {&lt;br /&gt;      case ("", (_, t)) =&gt; t&lt;br /&gt;      case (s, (0, t)) =&gt; s + " " + t&lt;br /&gt;      case (s, (1, t)) =&gt; s + " " + t.reverse&lt;br /&gt;    }&lt;br /&gt;  } + "."&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;or to name the parameters without declaring the types,&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;// ...&lt;br /&gt;  enumerate(ws(words)).foldLeft(""){&lt;br /&gt;    (stringSoFar, wordAndOddIndicator) =&gt; &lt;br /&gt;      (stringSoFar, wordAndOddIndicator) match {&lt;br /&gt;        case ("", (_, t)) =&gt; t&lt;br /&gt;        case (s, (0, t)) =&gt; s + " " + t&lt;br /&gt;        case (s, (1, t)) =&gt; s + " " + t.reverse&lt;br /&gt;      }&lt;br /&gt;  } + "."&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So that's the asymmetry: Scala named function definitions require parameter names and types, and the anonymous functions don't, because the parameter types can usually be inferred by usage. The Haskell "where" syntax is rather nice and a similar feature in Scala would be great... &lt;br /&gt;&lt;br /&gt;An imaginary Scala syntax for haskell style context based method definition:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;// ... &lt;br /&gt;enumerate(ws(words)).foldLeft("")(add)&lt;br /&gt;where {&lt;br /&gt;  def add = &lt;br /&gt;    (_, _) match {&lt;br /&gt;       case ("", (_, t)) =&gt; t&lt;br /&gt;       case (s, (0, t)) =&gt; s + " " + t&lt;br /&gt;       case (s, (1, t)) =&gt; s + " " + t.reverse&lt;br /&gt;    }&lt;br /&gt;  }  &lt;br /&gt;  // other defs&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It would just be an aliased anonymous functions which could (a) be used more than once in the expression and (b) simplify the overall expression compared to usage with anonymous functions. &lt;br /&gt;&lt;br /&gt;Just a thought!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-8277516002081143785?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/8277516002081143785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=8277516002081143785' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8277516002081143785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8277516002081143785'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2010/04/scala-asymmetry-in-function-definitions.html' title='Scala asymmetrical function definitions'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-8002254444997415155</id><published>2010-03-26T07:21:00.000-07:00</published><updated>2010-03-26T07:21:33.108-07:00</updated><title type='text'>The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory</title><content type='html'>I got this error after redeploying a web app to tomcat6 in myeclipse 8. &lt;br /&gt;&lt;br /&gt;org.apache.jasper.JasperException: Unable to compile class for JSP: &lt;br /&gt;&lt;br /&gt;An error occurred at line: 22 in the generated java file&lt;br /&gt;The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory&lt;br /&gt;&lt;br /&gt;Stacktrace:&lt;br /&gt; at org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:92)&lt;br /&gt; at org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:330)&lt;br /&gt; at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:423)&lt;br /&gt; at org.apache.jasper.compiler.Compiler.compile(Compiler.java:317)&lt;br /&gt;&lt;br /&gt;The reason was that &lt;br /&gt;  javax.servlet.jsp.jar&lt;br /&gt;  javax.servlet.jar&lt;br /&gt;&lt;br /&gt;had been copied to &lt;br /&gt;&lt;br /&gt;...\webapps\myapp\WEB-INF\lib&lt;br /&gt;&lt;br /&gt;And the versions conflicted with the tomcat versions &lt;br /&gt;&lt;br /&gt;Deleting &lt;br /&gt;  javax.servlet.jsp.jar&lt;br /&gt;  javax.servlet.jar&lt;br /&gt;from &lt;br /&gt;   ...\webapps\myapp\WEB-INF\lib&lt;br /&gt;&lt;br /&gt;fixed the problem&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-8002254444997415155?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/8002254444997415155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=8002254444997415155' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8002254444997415155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8002254444997415155'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2010/03/method-getjspapplicationcontextservletc.html' title='The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-5909409295908854589</id><published>2010-02-23T04:06:00.000-08:00</published><updated>2010-02-23T04:08:15.124-08:00</updated><title type='text'>Dynamically create spring bean</title><content type='html'>I used this in a dbunit test to create a dummy service layer bean dynamically. &lt;br /&gt;&lt;br /&gt;The rest of the beans were configured in xml files. I created this bean dynamically in the test so that I didn't have to pollute the xml config.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;// Dynamically create a DummyServiceToMakeCodeTransactional bean and register with spring&lt;br /&gt;     DefaultListableBeanFactory autowireCapableBeanFactory = (DefaultListableBeanFactory) getApplicationContext().getAutowireCapableBeanFactory();&lt;br /&gt;     AbstractBeanDefinition beanDefinition =&lt;br /&gt;          BeanDefinitionBuilder.rootBeanDefinition(&lt;br /&gt;               DummyServiceToMakeCodeTransactional.class.getName()).getBeanDefinition();&lt;br /&gt;     autowireCapableBeanFactory.registerBeanDefinition("DummyService", beanDefinition);&lt;br /&gt;     DummyServiceToMakeCodeTransactional bean = (DummyServiceToMakeCodeTransactional) &lt;br /&gt;     getApplicationContext().getBean("DummyService");&lt;br /&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/6818189468244276547-5909409295908854589?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/5909409295908854589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=5909409295908854589' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/5909409295908854589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/5909409295908854589'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2010/02/dynamically-creat-spring-beans.html' title='Dynamically create spring bean'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-2087193122993103459</id><published>2009-11-04T18:49:00.000-08:00</published><updated>2009-11-05T14:37:08.778-08:00</updated><title type='text'>C# Linq OrderBy, Scala SortWith and SortBy (and Scary Implicits)</title><content type='html'>Here is a tiny example of a little bit of linq at work in Visual Studio 2010 Beta2. Lets order a list of names in C#&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace TestOrderBy&lt;br /&gt;{&lt;br /&gt;    class Person&lt;br /&gt;    {&lt;br /&gt;        public Person(string firstName, string lastName, DateTime dateOfBirth)&lt;br /&gt;        {&lt;br /&gt;            FirstName = firstName;&lt;br /&gt;            LastName = lastName;&lt;br /&gt;            DateOfBirth = dateOfBirth;&lt;br /&gt;        }&lt;br /&gt;        public readonly string FirstName;&lt;br /&gt;        public readonly string LastName;&lt;br /&gt;        public readonly DateTime DateOfBirth;&lt;br /&gt;        override public string ToString()&lt;br /&gt;        {&lt;br /&gt;            return FirstName + ", " + LastName + " " + DateOfBirth.ToShortDateString();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            var people = new List&lt;person&gt;() {&lt;br /&gt;                new Person("Alan", "Kay", new DateTime(1973,12,1)),&lt;br /&gt;                new Person("James", "Gosling", new DateTime(1991,12,1)),&lt;br /&gt;                new Person("Anders", "Hejlsberg", new DateTime(1999,12,1)),&lt;br /&gt;                new Person("Martin", "Odersky", new DateTime(2000,12,1)),&lt;br /&gt;                new Person("Guido", "Van Rossum", new DateTime(2002,12,1)),&lt;br /&gt;                new Person("Yukihiro", "Matsumoto", new DateTime(1990,12,1))&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;            var peopleOrderedByDob = people.OrderBy(person =&amp;gt; person.DateOfBirth);&lt;br /&gt;            foreach (var p in peopleOrderedByDob)&lt;br /&gt;                Console.WriteLine(p);&lt;br /&gt;            Console.WriteLine();&lt;br /&gt;&lt;br /&gt;            var peopleOrderedNaturally = people.OrderBy(person =&amp;gt; person);&lt;br /&gt;            foreach (var p in peopleOrderedNaturally)&lt;br /&gt;                Console.WriteLine(p);&lt;br /&gt;            Console.WriteLine();&lt;br /&gt;&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/person&gt;&lt;/pre&gt;&lt;br /&gt;What happens when we run it: We get:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: plain"&gt;Alan, Kay 01/12/1973&lt;br /&gt;Yukihiro, Matsumoto 01/12/1990&lt;br /&gt;James, Gosling 01/12/1991&lt;br /&gt;Anders, Hejlsberg 01/12/1999&lt;br /&gt;Martin, Odersky 01/12/2000&lt;br /&gt;Guido, Van Rossum 01/12/2002&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So the clause "OrderBy(person =&amp;gt; person.DateOfBirth)" worked. Cool. C# knows how to compare birthdays.&lt;br /&gt;&lt;br /&gt;But then Kaboom! The debugger stops at line 42 with ArgumentExeption "At least one object must implement IComparable". So "people.OrderBy(person =&amp;gt; person)" was not checked at compile time. Wow! So lets implement IComparable on Person sorting on LastName:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;class Person  : IComparable&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;    int IComparable.CompareTo(object obj)&lt;br /&gt;    {&lt;br /&gt;        Person otherPerson = obj as Person;&lt;br /&gt;        if (otherPerson != null)&lt;br /&gt;            return this.LastName.CompareTo(otherPerson.LastName);&lt;br /&gt;        else&lt;br /&gt;            throw new ArgumentException("Object is not a Person");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And hey presto, C# knows how to sort people.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: plain"&gt;Alan, Kay 01/12/1973&lt;br /&gt;Yukihiro, Matsumoto 01/12/1990&lt;br /&gt;James, Gosling 01/12/1991&lt;br /&gt;Anders, Hejlsberg 01/12/1999&lt;br /&gt;Martin, Odersky 01/12/2000&lt;br /&gt;Guido, Van Rossum 01/12/2002&lt;br /&gt;&lt;br /&gt;James, Gosling 01/12/1991&lt;br /&gt;Anders, Hejlsberg 01/12/1999&lt;br /&gt;Alan, Kay 01/12/1973&lt;br /&gt;Yukihiro, Matsumoto 01/12/1990&lt;br /&gt;Martin, Odersky 01/12/2000&lt;br /&gt;Guido, Van Rossum 01/12/2002&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;These clauses: "person =&amp;gt; person.DateOfBirth" and "person =&amp;gt; person" are known in C# are known as keySelector and are part of the .net linq library. If you want to drink the full linq Kool-Aid you can write &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;var peopleOrderedByDob = &lt;br /&gt;      from p in people&lt;br /&gt;      orderby p.DateOfBirth&lt;br /&gt;      select p;&lt;br /&gt;&lt;br /&gt;foreach (var p in peopleOrderedByDob)&lt;br /&gt;  Console.WriteLine(p);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But its just doing the same thing under the covers.&lt;br /&gt;&lt;br /&gt;So lets do the same thing in Scala, using the sortWith method, which until 22 Oct 2009 was the only thing available. Lets sort by DateOfBirth first&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;import org.scala_tools.time.Imports._&lt;br /&gt;&lt;br /&gt;object TestSortBy {&lt;br /&gt;&lt;br /&gt;  case class Person(firstName: String, lastName: String, dateOfBirth: DateTime) &lt;br /&gt;  { &lt;br /&gt;    override def toString() = {&lt;br /&gt;      firstName + ", " + lastName + " " + DateTimeFormat.shortDate().print(dateOfBirth);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def main(args : Array[String]) : Unit = {    &lt;br /&gt;    val people = &lt;br /&gt;      Person("Alan", "Kay", new DateTime(1973,12,1,0,0,0,0))::&lt;br /&gt;      Person("James", "Gosling", new DateTime(1991,12,1,0,0,0,0))::&lt;br /&gt;      Person("Anders", "Hejlsberg", new DateTime(1999,12,1,0,0,0,0))::&lt;br /&gt;      Person("Martin", "Odersky", new DateTime(2000,12,1,0,0,0,0))::&lt;br /&gt;      Person("Guido", "Van Rossum", new DateTime(2002,12,1,0,0,0,0))::&lt;br /&gt;      Person("Yukihiro", "Matsumoto", new DateTime(1990,12,1,0,0,0,0))::Nil&lt;br /&gt;   &lt;br /&gt;    val peopleOrderedByDob = people.sortWith((p1,p2) =&amp;gt; p1.dateOfBirth &amp;lt; p2.dateOfBirth) &lt;br /&gt;    peopleOrderedByDob foreach println&lt;br /&gt;    println&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre class="brush: scala"&gt;&lt;/pre&gt;Which works just fine: &lt;br /&gt;&lt;pre class="brush: plain"&gt;&lt;/pre&gt;&lt;pre class="brush: plain"&gt;Alan, Kay 01/12/73&lt;br /&gt;Yukihiro, Matsumoto 01/12/90&lt;br /&gt;James, Gosling 01/12/91&lt;br /&gt;Anders, Hejlsberg 01/12/99&lt;br /&gt;Martin, Odersky 01/12/00&lt;br /&gt;Guido, Van Rossum 01/12/02&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So now for the ordering naturally too &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;val peopleOrderedNaturally = people.sortWith((p1,p2) =&amp;gt; p1 &amp;lt; p2) &lt;br /&gt;    peopleOrderedNaturally foreach println&lt;br /&gt;    println&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;but line 2 does not compile (unlike c# where this is a runtime error) because the compiler does not know how to compare one Person with another. Doh! So lets add Ordered[Person] to Person to tell the compiler how to judge people :) &lt;br /&gt;&lt;pre class="brush: scala"&gt;case class Person(firstName: String, lastName: String, dateOfBirth: DateTime) &lt;br /&gt;    extends Ordered[Person]&lt;br /&gt;  { &lt;br /&gt;    override def toString() = {&lt;br /&gt;      firstName + ", " + lastName + " " + DateTimeFormat.shortDate().print(dateOfBirth);&lt;br /&gt;    }&lt;br /&gt;    def compare(otherPerson: Person) = {&lt;br /&gt;      lastName.compareTo(otherPerson.lastName)&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;And hey presto, same results as C# &lt;br /&gt;&lt;pre class="brush: plain"&gt;Alan, Kay 01/12/73&lt;br /&gt;Yukihiro, Matsumoto 01/12/90&lt;br /&gt;James, Gosling 01/12/91&lt;br /&gt;Anders, Hejlsberg 01/12/99&lt;br /&gt;Martin, Odersky 01/12/00&lt;br /&gt;Guido, Van Rossum 01/12/02&lt;br /&gt;&lt;br /&gt;James, Gosling 01/12/91&lt;br /&gt;Anders, Hejlsberg 01/12/99&lt;br /&gt;Alan, Kay 01/12/73&lt;br /&gt;Yukihiro, Matsumoto 01/12/90&lt;br /&gt;Martin, Odersky 01/12/00&lt;br /&gt;Guido, Van Rossum 01/12/02&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Well that was easy. But if you look at Scala sortWith compared to C# OrderBy, you realize that in Scala you have to say how to do a comparison, whereas in C# you say what thing to order by. &lt;br /&gt;&lt;pre class="brush: scala"&gt;Scala&lt;br /&gt;  val peopleOrderedByDob = people.sortWith((p1,p2) =&amp;gt; p1.dateOfBirth &amp;lt; p2.dateOfBirth) &lt;br /&gt;C#&lt;br /&gt;  var peopleOrderedByDob = people.OrderBy(person =&amp;gt; person.DateOfBirth);&lt;br /&gt;&lt;/pre&gt;When the Scala team saw that the C# version was shorter, and worse still, more functional than Scala's imperativeness, there was a great silence of the lambdas and then they recursed and recursed until they'd invented the entire Scala implicits system described well &lt;a href="http://hestia.typepad.com/flatlander/2009/03/scala-for-c-programmers-part-5-implicits.html"&gt;here&lt;/a&gt; and &lt;a href="http://www.codecommit.com/blog/ruby/implicit-conversions-more-powerful-than-dynamic-typing"&gt;here&lt;/a&gt;. (Well maybe that wasn't quite how it happened...) So, very recently the sortBy method got added to the SeqLike trait as was kindly pointed out to me by Ismael Juma in an earlier post. So now we can write &lt;br /&gt;&lt;pre class="brush: scala"&gt;val peopleOrderedNaturallyWithSortBy = people.sortBy(person =&amp;gt; person) &lt;br /&gt;  peopleOrderedNaturallyWithSortBy foreach println&lt;br /&gt;  println    &lt;br /&gt;&lt;/pre&gt;and this works fine. (Note that if you take the "extends Ordered[Person]" away from Person then "people.sortBy(person =&amp;gt; person)" will not compile.) So how does it do it. Lets look at the signature of SortBy on the SeqLike trait. &lt;br /&gt;&lt;pre class="brush: scala"&gt;def sortBy[B](f: A =&amp;gt; B)(implicit ord: Ordering[B]): Repr&lt;br /&gt;&lt;/pre&gt;I'm not sure what Repr is, but the "implicit ord: Ordering[B])" is a suitable "thing" that knows how to order a B. In our case a B is a Person, which is an Ordered[Person] but not an Ordering[Person]. But Ordering.scala contains a trait LowPriorityOrderingImplicits with an implicit def that know how to "upgrade" an Ordered[Person] to an Ordering[Person] "thing" and that is then passed to the sortBy method to be used to get-the-job-done-tm. &lt;br /&gt;&lt;br /&gt;My head is about to explode. If you followed that last paragraph well done. If you didn't then read the next one instead. &lt;br /&gt;&lt;br /&gt;Anyhow, the compiler inserts an "implicit" "thing" into the last parameter of the sortBy method. And that "implicit" "thing" knows how to order people about into neat lines. It just works.&lt;br /&gt;&lt;br /&gt;So what about ordering by say firstName? &lt;br /&gt;&lt;pre class="brush: scala"&gt;val peopleOrderedByDobWithSortBy = people.sortBy(person =&amp;gt; person.firstName) &lt;br /&gt;    peopleOrderedNaturallyWithSortBy foreach println&lt;br /&gt;    println &lt;br /&gt;&lt;/pre&gt;Well that works fine. Turns out its because there is a whole stack of implicit object defs in Ordering.scala that provide instances of Ordering traits for the basic value types like String and Int etc.&lt;br /&gt;&lt;br /&gt;So what about ordering by say dateOfBirth? &lt;br /&gt;&lt;pre class="brush: scala"&gt;val peopleOrderedByDobWithSortBy = people.sortBy(person =&amp;gt; person.dateOfBirth) &lt;br /&gt;    peopleOrderedNaturallyWithSortBy foreach println&lt;br /&gt;    println    &lt;br /&gt;&lt;/pre&gt;It doesn't compile at line 2: "type arguments [org.scala_tools.time.imports.DateTime] do not conform to method ordered's type parameter bounds [A &amp;lt;: Ordered[A]]". Silly me, bah humbug! Its because a org.joda.time.DateTime isn't an Ordered[DateTime]. Now Scala-Time uses the pimp-my-library technique to upgrade org.joda.time.DateTime to RichDateTime, so we can try changing Scala-Time's RichDateTime to &lt;br /&gt;&lt;pre class="brush: scala"&gt;class RichDateTime(val underlying: DateTime) extends Ordered[RichDateTime]  {&lt;br /&gt;  def compare(y: RichDateTime): Int = {&lt;br /&gt;    return underlying.compareTo(y.underlying)&lt;br /&gt;  }&lt;br /&gt;  ...&lt;br /&gt;&lt;/pre&gt;but that still doesn't compile "people.sortBy(person =&amp;gt; person.dateOfBirth)" because, the compiler is not "upgrading" DateTime to RichDateTime.&lt;br /&gt;But we can say: &lt;br /&gt;&lt;pre class="brush: scala"&gt;val peopleOrderedByDobWithSortBy = people.sortBy(person =&amp;gt; RichDateTime(person.dateOfBirth)) &lt;br /&gt;&lt;/pre&gt;but thats not very pretty. So what's the answer? Put in an implicit object that knows how to order DateTime. &lt;br /&gt;&lt;pre class="brush: scala"&gt;implicit object DateTimeOrderingObject extends Ordering[DateTime] {&lt;br /&gt;  def compare(x: DateTime, y: DateTime) = x.compareTo(y)&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;That definition should live in the Scala-Time library, but for now, it can be in my program. Now this will compile: &lt;br /&gt;&lt;pre class="brush: scala"&gt;val peopleOrderedByDobWithSortBy = people.sortBy(person =&amp;gt; person.dateOfBirth) &lt;br /&gt;&lt;/pre&gt;and the code works.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;But now for something scary. &lt;/b&gt;If I accidentally import this definition from some library that I happen to be using &lt;br /&gt;&lt;pre class="brush: scala"&gt;implicit object SomeOtherPersonOrderingObjectInadvertentlyImported extends Ordering[Person] {&lt;br /&gt;def compare(p1: Person, p2: Person) =&amp;nbsp;&lt;/pre&gt;&lt;pre class="brush: scala"&gt;(p1.firstName+p1.lastName).compareTo(p2.firstName+p2.lastName)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Then my code breaks because the people are printed in a different order. The code still compiles, but I get the SomeOtherPersonOrderingObjectInadvertentlyImported object used to do the sorting of the People instead of People's normal ordering.&lt;br /&gt;&lt;br /&gt;If People line up in the wrong order then nobody cares, but lets call that class StocksToShortRightNow instead. Bang goes my Christmas bonus!&lt;br /&gt;&lt;br /&gt;I hope I am somehow wrong here, and this is a bug or I am thinking about this the wrong way. But it makes me nervous.&lt;br /&gt;&lt;br /&gt;Here is the complete code with the scary implicit commented out. &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;import org.scala_tools.time.Imports._&lt;br /&gt;&lt;br /&gt;object TestSortBy {&lt;br /&gt;  case class Person(firstName: String, lastName: String, dateOfBirth: DateTime) &lt;br /&gt;    extends Ordered[Person]&lt;br /&gt;  { &lt;br /&gt;    override def toString() = {&lt;br /&gt;      firstName + ", " + lastName + " " + DateTimeFormat.shortDate().print(dateOfBirth);&lt;br /&gt;    }&lt;br /&gt;    def compare(otherPerson: Person) = {&lt;br /&gt;      lastName.compareTo(otherPerson.lastName)&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // Comment this is and watch the behaviour change. This could be imported accidentally&lt;br /&gt;  // implicit object SomeOtherPersonOrderingObjectInadvertentlyImported &lt;br /&gt;  //   extends Ordering[Person] {&lt;br /&gt;  //   def compare(p1: Person, p2: Person) =&lt;br /&gt;  //    (p1.firstName+p1.lastName).compareTo(p2.firstName+p2.lastName)&lt;br /&gt;  // }&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  implicit object DateTimeOrderingObject extends Ordering[DateTime] {&lt;br /&gt;     def compare(x: DateTime, y: DateTime) = x.compareTo(y)&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  def main(args : Array[String]) : Unit = {&lt;br /&gt;    &lt;br /&gt;    val people = &lt;br /&gt;      Person("Alan", "Kay", new DateTime(1973,12,1,0,0,0,0))::&lt;br /&gt;      Person("James", "Gosling", new DateTime(1991,12,1,0,0,0,0))::&lt;br /&gt;      Person("Anders", "Hejlsberg", new DateTime(1999,12,1,0,0,0,0))::&lt;br /&gt;      Person("Martin", "Odersky", new DateTime(2000,12,1,0,0,0,0))::&lt;br /&gt;      Person("Guido", "Van Rossum", new DateTime(2002,12,1,0,0,0,0))::&lt;br /&gt;      Person("Yukihiro", "Matsumoto", new DateTime(1990,12,1,0,0,0,0))::Nil&lt;br /&gt;    &lt;br /&gt;    val peopleOrderedByDob = people.sortWith((p1,p2) =&amp;gt; p1.dateOfBirth &amp;lt; p2.dateOfBirth) &lt;br /&gt;    peopleOrderedByDob foreach println&lt;br /&gt;    println&lt;br /&gt;    &lt;br /&gt;    val peopleOrderedNaturally = people.sortWith((p1,p2) =&amp;gt; p1 &amp;lt; p2) &lt;br /&gt;    peopleOrderedNaturally foreach println&lt;br /&gt;    println&lt;br /&gt;&lt;br /&gt;    val peopleOrderedNaturallyWithSortBy = people.sortBy(person =&amp;gt; person) &lt;br /&gt;    peopleOrderedNaturallyWithSortBy foreach println&lt;br /&gt;    println    &lt;br /&gt;&lt;br /&gt;    val peopleOrderedByDobWithSortBy = people.sortBy(person =&amp;gt; person.dateOfBirth) &lt;br /&gt;    peopleOrderedNaturallyWithSortBy foreach println&lt;br /&gt;    println    &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;[Update: 2009-11-05]&lt;br /&gt;I &lt;a href="http://old.nabble.com/Implicits-bug-(or-feature-)-to26213631.html"&gt;posted &lt;/a&gt; a question about the SomeOtherPersonOrderingObjectInadvertentlyImported overriding the Person extends Ordered[Person] natural ordering. Here is Martin Odersky's response:&lt;br /&gt;Implicits that are explicitly declared or imported take precedence over implicits that come with the type. Btw you can find out what implicits are inserted by running scalac with&amp;nbsp;option -Xprint:typer. This will print out the tree after type checking.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-2087193122993103459?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/2087193122993103459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=2087193122993103459' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/2087193122993103459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/2087193122993103459'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/11/c-linq-orderby-scala-sortwith-and.html' title='C# Linq OrderBy, Scala SortWith and SortBy (and Scary Implicits)'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-712486457065438858</id><published>2009-11-02T17:57:00.000-08:00</published><updated>2009-11-05T03:22:28.896-08:00</updated><title type='text'>Using arithmetic expressions with Option[..] in Scala</title><content type='html'>&lt;a href="http://www.inc.com/magazine/20080401/how-hard-could-it-be-fire-and-motion.html"&gt;Fire and motion: Here is how it works. You fire at the enemy. That's the fire part. And you move forward at the same time. That's the motion. Get it?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Scala's answer to the "null" that everybody loves to hate is to use is the Option[T] types. The Option thing is described &lt;a href="http://programming-scala.labs.oreilly.com/ch02.html"&gt;here&lt;/a&gt; in section "Option, Some, and None: Avoiding nulls". &lt;br /&gt;Despite all the waffle, Option types are simple. A variable called v of class Option[Int] can have a value of either None or Some(123) where 123 is an example of the underlying value you actually care about. The value None is a real value, rather than an invalid reference as null is in Java or C#. If I want to test is whether v is None I can say v==None or v.isDefined() or !v.isEmpty(). If I want its value 123, I say v.getOrElse(0) where 0 is a default if its None. Easy. Or I can use a patten match. Easy too.&lt;br /&gt;&lt;br /&gt;A scenario I hit was doing various bits of arithmetic with stock prices. Now a stock price may not exists on a given date. But I may still want to write the code to try to do some calculation with the price. In Java I probably use a lot of null checks or set the price to a special value early on or something. C# gives you Nullable types which lets you say &lt;br /&gt;&lt;pre class="brush: csharp"&gt;double? price1 = null;&lt;br /&gt;double? ratio1 = 0.7;&lt;br /&gt;double? result = ratio1 * price1; // or some other complex expression&lt;br /&gt;Console.Write("{0,7:N2}", result);&lt;br /&gt;&lt;/pre&gt;In C#, if either price1 or ratio1 is null then result is null. The operators == and != do the right thing. Comparison using &amp;lt; and &amp;gt; requires a little &lt;a href="http://www.dotnet2themax.com/blogs/fbalena/PermaLink,guid,1638cc2f-b9a5-4654-a2ab-2e484b80d290.aspx"&gt;care&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So how do I do this in Scala? Well, if the Option type is what we are supposed to use then lets do it.&lt;br /&gt;&lt;pre class="brush: scala"&gt;val price1:Option[Double] = None&lt;br /&gt;  val ratio1:Option[Double] = Some(0.7)&lt;br /&gt;  val result:Option[Double] = price1 * ratio1&lt;br /&gt;  printf("%7.2f", result getOrElse -99999.99)&lt;br /&gt;&lt;/pre&gt;but line 3 does not compile because * is not a member of Option[Double].&lt;br /&gt;So a bit of googling and I find this clever-but-obscure trick:&lt;br /&gt;&lt;pre class="brush: scala"&gt;val result = &lt;br /&gt;    for (ratio1_alias &amp;lt;- ratio1; price1_alias &amp;lt;- price1)&lt;br /&gt;    yield ratio1_alias * price1_alias &lt;br /&gt;&lt;/pre&gt;It seems that you can iterate over an Option[..]: Its a sequence of either zero (for the None case) or one element (for the Some(123.0) case). The expression returns None if anything is None or Some(ratio1_alias * price1_alias) if not. Tricksy stuff. It works but boy does it suck from a readability point of view. Oh and all the vals need to be aliased. Can I have my C# nullable types back please? So after a question on the Scala-User mailing list "Rex Kerr-2" suggested using &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=179766"&gt;the pimp-my-library techique&lt;/a&gt; to add functionality to the Option[Double] class, by "upgrading" it to a RichOptionDouble to which I can add arithmetic operators. So I ended up with the non-generic (but simple and, better still, working) code: &lt;br /&gt;&lt;pre class="brush: scala"&gt;package org.scala_tools.option.math&lt;br /&gt;class RichOptionDouble(od:Option[Double]) extends Ordered[Option[Double]] {&lt;br /&gt;  def +(o:Option[Double]) = if (o==None) o else Some(numeric.plus(od.get,o.get))&lt;br /&gt;  def unary_-():Option[Double] = Some(-od.get) &lt;br /&gt;  def -(o:Option[Double]) = if (o==None) o else Some(od.get-o.get)&lt;br /&gt;  def *(o:Option[Double]) = if (o==None) o else Some(od.get*o.get)&lt;br /&gt;  def /(o:Option[Double]) = if (o==None) o else Some(od.get/o.get)&lt;br /&gt;  def compare(y: Option[Double]): Int = {&lt;br /&gt;    if (od.isEmpty) return if (y.isEmpty) 0 else 1 &lt;br /&gt;    if (y.isEmpty) return -1 &lt;br /&gt;    // This is what Scala RichDouble does&lt;br /&gt;    return java.lang.Double.compare(od.getOrElse(0d), y.getOrElse(0d))&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object RichOptionDoubleNone extends RichOptionDouble(None) { &lt;br /&gt;  override def +(o:Option[Double]) = None&lt;br /&gt;  override def unary_-() = None&lt;br /&gt;  override def -(o:Option[Double]) = None&lt;br /&gt;  override def *(o:Option[Double]) = None&lt;br /&gt;  override def /(o:Option[Double]) = None&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;trait Implicits {&lt;br /&gt;  implicit def optiondouble2richoptiondouble(od:Option[Double]) = {&lt;br /&gt;    if (od==None) RichOptionDoubleNone else new RichOptionDouble(od)&lt;br /&gt;  }&lt;br /&gt;  implicit def double2optiondouble(d:Double) = Some(d)&lt;br /&gt;  implicit def int2optiondouble(i:Int) = Some(i.toDouble) &lt;br /&gt;  implicit def double2richoptiondouble(d:Double) = new RichOptionDouble(Some(d)) &lt;br /&gt;  implicit def int2richoptiondouble(i:Int) = new RichOptionDouble(Some(i.toDouble)) &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Modelled on technique in Scala-Time&lt;br /&gt;object Imports extends Implicits&lt;br /&gt;&lt;/pre&gt;So now I can say: &lt;br /&gt;&lt;pre class="brush: scala"&gt;import org.scala_tools.option.math.Imports._  &lt;br /&gt; &lt;br /&gt;object Bar {&lt;br /&gt;  def main(args : Array[String]) : Unit = {&lt;br /&gt;    val price1 = None&lt;br /&gt;    val price2 = Some(123.45)&lt;br /&gt;    val ratio1 = Some(0.7)&lt;br /&gt;    val result1 = price1 * ratio1&lt;br /&gt;    val result2 = price2 * ratio1 / 2 + 7.0&lt;br /&gt;    printf("%7.2f", result1 getOrElse -99999.99)&lt;br /&gt;    printf("%7.2f", result2 getOrElse -99999.99) &lt;br /&gt;    printf(" %s\n", result1 &amp;gt; result2) &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Which prints &lt;br /&gt;&lt;pre class="brush: plain"&gt;-99999.99  86.41 true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not ground breaking stuff. But still nice to get there in the end. It feels something like this (probably in generic form) should be in the core libraries,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-712486457065438858?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/712486457065438858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=712486457065438858' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/712486457065438858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/712486457065438858'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/11/using-arithmetic-expression-with-option.html' title='Using arithmetic expressions with Option[..] in Scala'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-2617121010552768110</id><published>2009-11-01T08:09:00.000-08:00</published><updated>2009-11-02T05:08:39.285-08:00</updated><title type='text'>Scala almost as good as C# .NET4?</title><content type='html'>Disclaimer: I am primarily a Java developer with some experience in C# NET 2, Ruby and Javascript, + few of others from the C derived stable. I'm learning Scala and I am not using it in paid work yet. (Offers welcome!)&lt;br /&gt;&lt;br /&gt;So far my posts have been about Scala, and learning about functional programming, but this is a bit of a diversion. In the previous post &lt;a href="http://quoiquilensoit.blogspot.com/2009/10/becoming-really-rich-with-scala.html"&gt;Becoming really rich with scala&lt;/a&gt;, I  translated a very nice example of some C# .NET 4 code to Scala using alot of idiomatic Scala.  The C# code stands up very well in comparison. Much to my surprise, I think that C# has the edge overall although its a close call. I dread to think what the equivalent code would look like in Java. This exercise made me realise just how far behind Java is compared to C# especially the version coming in .NET4. While the java world has been bickering about how to do proper closures without breaking backwards compatibility, C# added them long ago. Then C# added linq and updated the libraries to use the new features. Now Plinq is being built on that foundation. IMO, this combination has moved C# up to a totally different level compared to Java. &lt;br /&gt;&lt;br /&gt;The C# features that caught my eye are:&lt;br /&gt;&lt;br /&gt;a) The functional features and linq can make C# as *readably* concise as Scala, and all the imperative stuff is still there if you want it.  &lt;br /&gt;&lt;br /&gt;b) The way that the well known SQL vocabulary "select", "where", "orderBy" has been used C# instead of "map" and "filter" and "sortBy" in Scala (and others). This is subtle point but it seems very important to me. C#/Java developers are familiar with SQL but not necessaryily map, filter, etc. This choice of familiar vocabulary is important.&lt;br /&gt;&lt;br /&gt;c) C# OrderBy(s =&gt; s.LRS) vs Scala .sortWith((elem1, elem2) =&gt; elem1.LRS &lt;= elem2.LRS). This small point may appears trivial, but IMO is a huge mindset win for C#. In list.OrderBy(s =&gt; s.LRS), you are saying *what* you want and not, as in Scala, not *how* to do it; list.sortWith((elem1, elem2) =&gt; elem1.LRS &lt;= elem2.LRS). This principle is what makes SQL so powerful, but of course here is is being used with C# lists. I'm sure this is just the tip of the iceberg for the way that this principle can be used. &lt;br&gt;&lt;br /&gt;d) [apologies: I added this point since posting the original on which the first 8 comments are based]. &lt;a href="http://blogs.msdn.com/ericgu/archive/2004/05/27/143221.aspx"&gt;Nullable types&lt;/a&gt;. This is a sane way of dealing with arithmetic where variables can be null. Java just offers huge amounts of ==null? boilerplate. Scala offers Option[Double/etc] which is a start, but you can't do arithmetic expressions using Option variables out-of-the-box. Its *fairly* easy to &lt;a href="http://old.nabble.com/Option-Double--arithmetic-operators-td26015945.html"&gt;add arithmetic expressions to Option types&lt;/a&gt; but its not in the core libraries.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;The Java world makes a lot of noise about the other JVM languages that are "better" in some way that Java: JavaFX, Clojure, Groovy, JRuby, Fan, or Scala. But C# .NET4 has raised the bar up very very high with C# 4. Nobody in the alternative JVM language world should feel complacent! (Well (except &lt;a href="http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey"&gt;Rich Hickey&lt;/a&gt;, ((!)))).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-2617121010552768110?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/2617121010552768110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=2617121010552768110' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/2617121010552768110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/2617121010552768110'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/11/scala-almost-as-good-as-c-net4.html' title='Scala almost as good as C# .NET4?'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-3578196186974842880</id><published>2009-10-28T18:53:00.001-07:00</published><updated>2009-10-29T00:39:46.393-07:00</updated><title type='text'>Becoming really rich with Scala</title><content type='html'>A few posts back I said that &lt;a style="font-family: verdana;" href="http://blogs.msdn.com/lucabol/archive/2009/09/22/becoming-really-rich-with-c.aspx"&gt;Becoming really rich with C#&lt;/a&gt; was a great example of what's coming in the version of C# in Visual Studio 2010 and it makes it obvious that C# is leaving Java in the dust. Now that the Visual Studio 2010 beta 2 is available, you can download Luca's code and try it out. &lt;br /&gt;&lt;br /&gt;For this post, I've translated the C# code into Scala while trying to preserve the C# original style. To do this I have added support code in order to match the C# style. This was easy and shows off Scala's extensibility. &lt;br /&gt;&lt;br /&gt;The features/libraries or libraries added or used to do this are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Scala-Time:  A Java Joda Time library wrapper.&lt;/li&gt;&lt;li&gt;The "using" block from Martin Odersky's FOSDEM '09 talk&lt;/li&gt;&lt;li&gt;An EventHandler class for simulating C# Events&lt;/li&gt;&lt;li&gt;The Jetty HTTPClient from Eclipse that I wrapped to resemble the C# WebClient api.&lt;/li&gt;&lt;li&gt;Artithmetic operations for Option[Double]. (Option[Double] is Scala's equivalent of the C# nullable type double? In C# you can use double? variables in expresssions, with expressions returning null if any part of the expression is null. In Scala, you can't use Option[Double] in arithmetic expressions out of the box, but its very easy to add this ability in a small library.&lt;/li&gt;&lt;li&gt;The Scala code is written with the latest 2.8 pre version of Scala and uses one or two features from its latest standard library not present in the latest stable release.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;While the Scala is slighly shorter than the C# code, it is supported by extra code or libraries that I have  found or had to write. (You'll find all the Scala code in this &lt;a href="http://dl.getdropbox.com/u/2253328/workspace_BecomingReallyRichWithCSharp.zip"&gt;download link here&lt;/a&gt;). C# already has using blocks, Events and reasonable datetime management, a WebClient and Nullable double types that handle arithmentic operations sensibly.&lt;br /&gt;&lt;br /&gt;For whatever reason, the Scala code runs much faster than the c# code, but there is a large amount of internet access involved and I suspect that the C# web client should be configured to use more threads. [Update: Luca just suggested I comment out the C# line ServicePointManager.DefaultConnectionLimit = 10; and this does indeed make the C# code much faster.]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;th&gt;Original C#&lt;/th&gt;&lt;th&gt;Scala&lt;br /&gt;See notes after the table&lt;/th&gt;&lt;tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;pre class="brush: csharp; gutter: false;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Net;&lt;br /&gt;using System.Threading;&lt;br /&gt;using System.Threading.Tasks;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;br /&gt;namespace ETFAnalyzer {&lt;br /&gt;&lt;br /&gt;struct Event {&lt;br /&gt;  internal Event(DateTime date, double price) { Date = date; Price = price; }&lt;br /&gt;  internal readonly DateTime Date;&lt;br /&gt;  internal readonly double Price;&lt;br /&gt;}&lt;br /&gt;class Summary {&lt;br /&gt;  internal Summary(string ticker, string name, string assetClass,&lt;br /&gt;          string assetSubClass, double? weekly, double? fourWeeks,&lt;br /&gt;          double? threeMonths, double? sixMonths, double? oneYear,&lt;br /&gt;          double? stdDev, double price, double? mav200) {&lt;br /&gt;    Ticker = ticker;&lt;br /&gt;    Name = name;&lt;br /&gt;    AssetClass = assetClass;&lt;br /&gt;    AssetSubClass = assetSubClass;&lt;br /&gt;    // Abracadabra ...&lt;br /&gt;    LRS = (fourWeeks + threeMonths + sixMonths + oneYear) / 4;&lt;br /&gt;    Weekly = weekly;&lt;br /&gt;    FourWeeks = fourWeeks;&lt;br /&gt;    ThreeMonths = threeMonths;&lt;br /&gt;    SixMonths = sixMonths;&lt;br /&gt;    OneYear = oneYear;&lt;br /&gt;    StdDev = stdDev;&lt;br /&gt;    Mav200 = mav200;&lt;br /&gt;    Price = price;&lt;br /&gt;  }&lt;br /&gt;  internal readonly string Ticker;&lt;br /&gt;  internal readonly string Name;&lt;br /&gt;  internal readonly string AssetClass;&lt;br /&gt;  internal readonly string AssetSubClass;&lt;br /&gt;  internal readonly double? LRS;&lt;br /&gt;  internal readonly double? Weekly;&lt;br /&gt;  internal readonly double? FourWeeks;&lt;br /&gt;  internal readonly double? ThreeMonths;&lt;br /&gt;  internal readonly double? SixMonths;&lt;br /&gt;  internal readonly double? OneYear;&lt;br /&gt;  internal readonly double? StdDev;&lt;br /&gt;  internal readonly double? Mav200;&lt;br /&gt;  internal double Price;&lt;br /&gt;&lt;br /&gt;  internal static void Banner() {&lt;br /&gt;    Console.Write("{0,-6}", "Ticker");&lt;br /&gt;    Console.Write("{0,-50}", "Name");&lt;br /&gt;    Console.Write("{0,-12}", "Asset Class");&lt;br /&gt;    Console.Write("{0,4}", "RS");&lt;br /&gt;    Console.Write("{0,4}", "1Wk");&lt;br /&gt;    Console.Write("{0,4}", "4Wk");&lt;br /&gt;    Console.Write("{0,4}", "3Ms");&lt;br /&gt;    Console.Write("{0,4}", "6Ms");&lt;br /&gt;    Console.Write("{0,4}", "1Yr");&lt;br /&gt;    Console.Write("{0,6}", "Vol");&lt;br /&gt;    Console.WriteLine("{0,2}", "Mv");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  internal void Print() {&lt;br /&gt;&lt;br /&gt;    Console.Write("{0,-6}", Ticker);&lt;br /&gt;    Console.Write("{0,-50}", new String(Name.Take(48).ToArray()));&lt;br /&gt;    Console.Write("{0,-12}", new String(AssetClass.Take(10).ToArray()));&lt;br /&gt;    Console.Write("{0,4:N0}", LRS * 100);&lt;br /&gt;    Console.Write("{0,4:N0}", Weekly * 100);&lt;br /&gt;    Console.Write("{0,4:N0}", FourWeeks * 100);&lt;br /&gt;    Console.Write("{0,4:N0}", ThreeMonths * 100);&lt;br /&gt;    Console.Write("{0,4:N0}", SixMonths * 100);&lt;br /&gt;    Console.Write("{0,4:N0}", OneYear * 100);&lt;br /&gt;    Console.Write("{0,6:N0}", StdDev * 100);&lt;br /&gt;    if (Price &lt;= Mav200)&lt;br /&gt;      Console.WriteLine("{0,2}", "X");&lt;br /&gt;    else&lt;br /&gt;      Console.WriteLine();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class TimeSeries {&lt;br /&gt;  internal readonly string Ticker;&lt;br /&gt;  readonly DateTime _start;&lt;br /&gt;  readonly Dictionary&amp;lt;DateTime, double&gt; _adjDictionary;&lt;br /&gt;  readonly string _name;&lt;br /&gt;  readonly string _assetClass;&lt;br /&gt;  readonly string _assetSubClass;&lt;br /&gt;&lt;br /&gt;  internal TimeSeries(string ticker, string name, string assetClass, string assetSubClass, IEnumerable&amp;lt;event&gt; events) {&lt;br /&gt;    Ticker = ticker;&lt;br /&gt;    _name = name;&lt;br /&gt;    _assetClass = assetClass;&lt;br /&gt;    _assetSubClass = assetSubClass;&lt;br /&gt;    _start = events.Last().Date;&lt;br /&gt;    _adjDictionary = events.ToDictionary(e =&gt; e.Date, e =&gt; e.Price);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  bool GetPrice(DateTime when, out double price, out double shift) {&lt;br /&gt;    // To nullify the effect of hours/min/sec/millisec being different from 0&lt;br /&gt;    when = new DateTime(when.Year, when.Month, when.Day);&lt;br /&gt;    var found = false;&lt;br /&gt;    shift = 1;&lt;br /&gt;    double aPrice = 0;&lt;br /&gt;    while (when &gt;= _start &amp;&amp; !found) {&lt;br /&gt;      if (_adjDictionary.TryGetValue(when, out aPrice)) {&lt;br /&gt;        found = true;&lt;br /&gt;      }&lt;br /&gt;      when = when.AddDays(-1);&lt;br /&gt;      shift -= 1;&lt;br /&gt;    }&lt;br /&gt;    price = aPrice;&lt;br /&gt;    return found;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  double? GetReturn(DateTime start, DateTime end) {&lt;br /&gt;    var startPrice = 0.0;&lt;br /&gt;    var endPrice = 0.0;&lt;br /&gt;    var shift = 0.0;&lt;br /&gt;    var foundEnd = GetPrice(end, out endPrice, out shift);&lt;br /&gt;    var foundStart = GetPrice(start.AddDays(shift), out startPrice, out shift);&lt;br /&gt;    if (!foundStart || !foundEnd)&lt;br /&gt;      return null;&lt;br /&gt;    else&lt;br /&gt;      return endPrice / startPrice - 1;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  internal double? LastWeekReturn() {&lt;br /&gt;    return GetReturn(DateTime.Now.AddDays(-7), DateTime.Now);&lt;br /&gt;  }&lt;br /&gt;  internal double? Last4WeeksReturn() {&lt;br /&gt;    return GetReturn(DateTime.Now.AddDays(-28), DateTime.Now);&lt;br /&gt;  }&lt;br /&gt;  internal double? Last3MonthsReturn() {&lt;br /&gt;    return GetReturn(DateTime.Now.AddMonths(-3), DateTime.Now);&lt;br /&gt;  }&lt;br /&gt;  internal double? Last6MonthsReturn() {&lt;br /&gt;    return GetReturn(DateTime.Now.AddMonths(-6), DateTime.Now);&lt;br /&gt;  }&lt;br /&gt;  internal double? LastYearReturn() {&lt;br /&gt;    return GetReturn(DateTime.Now.AddYears(-1), DateTime.Now);&lt;br /&gt;  }&lt;br /&gt;  internal double? StdDev() {&lt;br /&gt;    var now = DateTime.Now;&lt;br /&gt;    now = new DateTime(now.Year, now.Month, now.Day);&lt;br /&gt;    var limit = now.AddYears(-3);&lt;br /&gt;    var rets = new List&amp;lt;double&gt;();&lt;br /&gt;    while (now &gt;= _start.AddDays(12) &amp;&amp; now &gt;= limit) {&lt;br /&gt;      var ret = GetReturn(now.AddDays(-7), now);&lt;br /&gt;      rets.Add(ret.Value);&lt;br /&gt;      now = now.AddDays(-7);&lt;br /&gt;    }&lt;br /&gt;    var mean = rets.Average();&lt;br /&gt;    var variance = rets.Select(r =&gt; Math.Pow(r - mean, 2)).Sum();&lt;br /&gt;    var weeklyStdDev = Math.Sqrt(variance / rets.Count);&lt;br /&gt;    return weeklyStdDev * Math.Sqrt(40);&lt;br /&gt;  }&lt;br /&gt;  internal double? MAV200() {&lt;br /&gt;    return _adjDictionary.ToList()&lt;br /&gt;           .OrderByDescending(k =&gt; k.Key)&lt;br /&gt;           .Take(200).Average(k =&gt; k.Value);&lt;br /&gt;  }&lt;br /&gt;  internal double TodayPrice() {&lt;br /&gt;    var price = 0.0;&lt;br /&gt;    var shift = 0.0;&lt;br /&gt;    GetPrice(DateTime.Now, out price, out shift);&lt;br /&gt;    return price;&lt;br /&gt;  }&lt;br /&gt;  internal Summary GetSummary() {&lt;br /&gt;    return new Summary(Ticker, _name, _assetClass, _assetSubClass,&lt;br /&gt;           LastWeekReturn(), Last4WeeksReturn(), Last3MonthsReturn(),&lt;br /&gt;           Last6MonthsReturn(), LastYearReturn(), StdDev(), TodayPrice(), &lt;br /&gt;           MAV200());&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Program {&lt;br /&gt;&lt;br /&gt;  static string CreateUrl(string ticker, DateTime start, DateTime end)&lt;br /&gt;  {&lt;br /&gt;    return @"http://ichart.finance.yahoo.com/table.csv?s=" + ticker + &lt;br /&gt;      "&amp;a="+(start.Month - 1).ToString()+"&amp;b="+start.Day.ToString()+"&amp;c="+start.Year.ToString() + &lt;br /&gt;      "&amp;d="+(end.Month - 1).ToString()+"&amp;e="+end.Day.ToString()+"&amp;f="+end.Year.ToString() + &lt;br /&gt;      "&amp;g=d&amp;ignore=.csv";&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static void Main(string[] args) {&lt;br /&gt;    // If you rise this above 5 you tend to get frequent connection closing on my machine&lt;br /&gt;    // I'm not sure if it is msft network or yahoo web service&lt;br /&gt;    ServicePointManager.DefaultConnectionLimit = 10;&lt;br /&gt;&lt;br /&gt;    var tickers =&lt;br /&gt;      File.ReadAllLines("ETFTest.csv")&lt;br /&gt;      .Skip(1)&lt;br /&gt;      .Select(l =&gt; l.Split(new[] { ',' }))&lt;br /&gt;      .Where(v =&gt; v[2] != "Leveraged")&lt;br /&gt;      .Select(values =&gt; Tuple.Create(values[0], values[1], values[2], values[3]))&lt;br /&gt;      .ToArray();&lt;br /&gt;&lt;br /&gt;    var len = tickers.Length;&lt;br /&gt;&lt;br /&gt;    var start = DateTime.Now.AddYears(-2);&lt;br /&gt;    var end = DateTime.Now;&lt;br /&gt;    var cevent = new CountdownEvent(len);&lt;br /&gt;    var summaries = new Summary[len];&lt;br /&gt;    &lt;br /&gt;    for(var i = 0; i &lt; len; i++)  {&lt;br /&gt;      var t = tickers[i];&lt;br /&gt;      var url = CreateUrl(t.Item1, start, end);&lt;br /&gt;      using (var webClient = new WebClient()) {&lt;br /&gt;        webClient.DownloadStringCompleted +=&lt;br /&gt;                        new DownloadStringCompletedEventHandler(downloadStringCompleted);&lt;br /&gt;        webClient.DownloadStringAsync(new Uri(url), Tuple.Create(t, cevent, summaries, i));&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    cevent.Wait();&lt;br /&gt;    Console.WriteLine("\n");&lt;br /&gt;&lt;br /&gt;    var top15perc =&lt;br /&gt;        summaries&lt;br /&gt;        .Where(s =&gt; s.LRS.HasValue)&lt;br /&gt;        .OrderByDescending(s =&gt; s.LRS)&lt;br /&gt;        .Take((int)(len * 0.15));&lt;br /&gt;    var bottom15perc =&lt;br /&gt;        summaries&lt;br /&gt;        .Where(s =&gt; s.LRS.HasValue)&lt;br /&gt;        .OrderBy(s =&gt; s.LRS)&lt;br /&gt;        .Take((int)(len * 0.15));&lt;br /&gt;&lt;br /&gt;    Console.WriteLine();&lt;br /&gt;    Summary.Banner();&lt;br /&gt;    Console.WriteLine("TOP 15%");&lt;br /&gt;    foreach(var s in top15perc)&lt;br /&gt;      s.Print();&lt;br /&gt;&lt;br /&gt;    Console.WriteLine();&lt;br /&gt;    Console.WriteLine("Bottom 15%");&lt;br /&gt;    foreach (var s in bottom15perc)&lt;br /&gt;      s.Print();&lt;br /&gt;      &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  static void downloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) {&lt;br /&gt;    var bigTuple = (Tuple&amp;lt;Tuple&amp;lt;string, string, string, string&gt;, CountdownEvent, Summary[], int&gt;)e.UserState;&lt;br /&gt;    var tuple = bigTuple.Item1;&lt;br /&gt;    var cevent = bigTuple.Item2;&lt;br /&gt;    var summaries = bigTuple.Item3;&lt;br /&gt;    var i = bigTuple.Item4;&lt;br /&gt;    var ticker = tuple.Item1;&lt;br /&gt;    var name = tuple.Item2;&lt;br /&gt;    var asset = tuple.Item3;&lt;br /&gt;    var subAsset = tuple.Item4;&lt;br /&gt;&lt;br /&gt;    if (e.Error == null) {&lt;br /&gt;      var adjustedPrices =&lt;br /&gt;          e.Result&lt;br /&gt;          .Split(new[] { '\n' })&lt;br /&gt;          .Skip(1)&lt;br /&gt;          .Select(l =&gt; l.Split(new[] { ',' }))&lt;br /&gt;          .Where(l =&gt; l.Length == 7)&lt;br /&gt;          .Select(v =&gt; new Event(DateTime.Parse(v[0]), Double.Parse(v[6])));&lt;br /&gt;&lt;br /&gt;      var timeSeries = new TimeSeries(ticker, name, asset, subAsset, adjustedPrices);&lt;br /&gt;      summaries[i] = timeSeries.GetSummary();&lt;br /&gt;      cevent.Signal();&lt;br /&gt;      Console.Write("{0} ", ticker);&lt;br /&gt;    } else {&lt;br /&gt;      Console.WriteLine("[{0} ERROR] ", ticker);&lt;br /&gt;      summaries[i] = new Summary(ticker,name,"ERROR","ERROR",0,0,0,0,0,0,0,0); &lt;br /&gt;      cevent.Signal();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt; &lt;td&gt;&lt;br /&gt;&lt;pre class="brush: scala; gutter: false;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;package etf.analyzer&lt;br /&gt;&lt;br /&gt;import scala.io.Source&lt;br /&gt;import org.scala_tools.time.Imports._&lt;br /&gt;import org.scala_tools.option.math.Imports._  &lt;br /&gt;import org.joda.time.Days&lt;br /&gt;import org.scala_tools.using.Using&lt;br /&gt;import org.scala_tools.web.WebClient&lt;br /&gt;import org.scala_tools.web.WebClientConnections&lt;br /&gt;import org.scala_tools.web.DownloadStringCompletedEventArgs &lt;br /&gt;import java.io.File&lt;br /&gt;import java.util.concurrent.CountDownLatch &lt;br /&gt;&lt;br /&gt;case class Event (date : DateTime, price : Double) {}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;case class Summary (&lt;br /&gt;  ticker : String, name : String, assetClass : String,&lt;br /&gt;  assetSubClass : String, weekly : Option[Double], &lt;br /&gt;  fourWeeks : Option[Double], threeMonths : Option[Double], &lt;br /&gt;  sixMonths : Option[Double], oneYear : Option[Double],&lt;br /&gt;  stdDev : Double, price : Double, mav200 : Double &lt;br /&gt;) {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  // Abracadabra ...&lt;br /&gt;  val LRS = (fourWeeks + threeMonths + sixMonths+ oneYear) / 4   &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def banner() = {&lt;br /&gt;    printf("%-6s", "Ticker")&lt;br /&gt;    printf("%-50s", "Name")&lt;br /&gt;    printf("%-12s", "Asset Class")&lt;br /&gt;    printf("%4s", "RS")&lt;br /&gt;    printf("%4s", "1Wk")&lt;br /&gt;    printf("%4s", "4Wk")&lt;br /&gt;    printf("%4s", "3Ms")&lt;br /&gt;    printf("%4s", "6Ms")&lt;br /&gt;    printf("%4s", "1Yr")&lt;br /&gt;    printf("%6s", "Vol")&lt;br /&gt;    printf("%2s\n", "Mv")&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  def print() = {&lt;br /&gt;  &lt;br /&gt;    printf("%-6s", ticker);&lt;br /&gt;    printf("%-50s", new String(name.toArray.take(48)))&lt;br /&gt;    printf("%-12s", new String(assetClass.toArray.take(10)));&lt;br /&gt;    printf("%4.0f", LRS * 100 getOrElse null)&lt;br /&gt;    printf("%4.0f", weekly * 100 getOrElse null)&lt;br /&gt;    printf("%4.0f", fourWeeks * 100 getOrElse null)&lt;br /&gt;    printf("%4.0f", threeMonths * 100 getOrElse null)&lt;br /&gt;    printf("%4.0f", sixMonths * 100 getOrElse null)&lt;br /&gt;    printf("%4.0f", oneYear * 100 getOrElse null)&lt;br /&gt;    printf("%6.0f", stdDev * 100);&lt;br /&gt;    if (price &lt;= mav200) {&lt;br /&gt;      printf("%2s\n", "X");&lt;br /&gt;    } else {&lt;br /&gt;      println();&lt;br /&gt;    }&lt;br /&gt;  }  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case class TimeSeries (&lt;br /&gt;    ticker : String, name : String, assetClass : String, &lt;br /&gt;    assetSubClass : String, private events : Iterable[Event]&lt;br /&gt;) {&lt;br /&gt;  &lt;br /&gt;  private val _adjDictionary : Map[DateTime, Double] &lt;br /&gt;              = Map() ++ events.map(e =&gt; (e.date -&gt; e.price))&lt;br /&gt;  private val _start = events.last.date&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  // Add the sum and average function to all Iterables[Double] used locally&lt;br /&gt;  private implicit def iterableWithSumAndAverage(c: Iterable[Double]) = new { &lt;br /&gt;    def sum = c.foldLeft(0.0)(_ + _) &lt;br /&gt;    def average = sum / c.size&lt;br /&gt;  }  &lt;br /&gt;  &lt;br /&gt;  def getPrice(whenp : DateTime) : Option[(Double,Int)] =  {&lt;br /&gt;    var when = new DateTime(whenp.year.get,whenp.month.get,whenp.day.get,0,0,0,0)&lt;br /&gt;    var found = false&lt;br /&gt;    var shift = 1&lt;br /&gt;    var aPrice = 0.0&lt;br /&gt;    while (when &gt;= _start &amp;&amp; !found) {&lt;br /&gt;        if (_adjDictionary.contains(when)) {&lt;br /&gt;            aPrice = _adjDictionary(when)&lt;br /&gt;            found = true&lt;br /&gt;        }&lt;br /&gt;        when = when - 1.days&lt;br /&gt;        shift -= 1&lt;br /&gt;    }&lt;br /&gt;    // Either return the price and the shift or None if no price was found&lt;br /&gt;    if (found) Some(aPrice,shift) else return None&lt;br /&gt;  }  &lt;br /&gt;&lt;br /&gt;  def getReturn(start: DateTime, end: DateTime) : Option[Double] = {&lt;br /&gt;    for {&lt;br /&gt;      (endPrice,daysBefore) &lt;- getPrice(end) &lt;br /&gt;      (startPrice,_) &lt;- getPrice(start + daysBefore.days)&lt;br /&gt;    } yield &lt;br /&gt;      (endPrice / startPrice - 1.0)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  private def lastWeekReturn   &lt;br /&gt;    = getReturn(DateTime.now - 7.days, DateTime.now)&lt;br /&gt;&lt;br /&gt;  private def last4WeeksReturn &lt;br /&gt;    = getReturn(DateTime.now - 28.days, DateTime.now)&lt;br /&gt;  &lt;br /&gt;  private def last3MonthsReturn&lt;br /&gt;    = getReturn(DateTime.now - 3.months, DateTime.now)&lt;br /&gt;  &lt;br /&gt;  private def last6MonthsReturn&lt;br /&gt;    = getReturn(DateTime.now - 6.months, DateTime.now)&lt;br /&gt;  &lt;br /&gt;  private def lastYearReturn   &lt;br /&gt;    = getReturn(DateTime.now - 1.years, DateTime.now)  &lt;br /&gt;  &lt;br /&gt;  def stdDev(): Double = {&lt;br /&gt;    val today = DateTime.now&lt;br /&gt;    val limit = today - 3.years&lt;br /&gt;    val dates = Iterator.iterate(today)(_ - 7.days)&lt;br /&gt;                .takeWhile (d =&gt; d &gt;= (_start + 12.days) &amp;&amp; d &gt;= limit)&lt;br /&gt;                .toList&lt;br /&gt;    val rets = dates.map(d =&gt; getReturn(d - 7.days, d).get)&lt;br /&gt;    val mean = rets.average&lt;br /&gt;    val variance = rets.map(r =&gt; Math.pow(r - mean, 2)).average&lt;br /&gt;    val weeklyStdDev = Math.sqrt(variance);&lt;br /&gt;    return weeklyStdDev * Math.sqrt(40);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def mav200(): Double = {&lt;br /&gt;    return _adjDictionary.toList&lt;br /&gt;           .sortWith((elem1, elem2) =&gt; elem1._1 &gt;= elem2._1)&lt;br /&gt;           .take(200).map(keyValue =&gt; keyValue._2).average&lt;br /&gt;  }&lt;br /&gt;  def todayPrice() : Double = {&lt;br /&gt;    getPrice(DateTime.now) match {&lt;br /&gt;      case None =&gt; 0.0&lt;br /&gt;      case Some((price,_)) =&gt; price &lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  def getSummary() = &lt;br /&gt;    Summary(ticker, name, assetClass, assetSubClass, &lt;br /&gt;      lastWeekReturn, last4WeeksReturn, last3MonthsReturn, &lt;br /&gt;      last6MonthsReturn, lastYearReturn, stdDev, todayPrice, &lt;br /&gt;      mav200)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object Program extends Using {&lt;br /&gt;&lt;br /&gt;  def createUrl(ticker: String, start: DateTime, end: DateTime) : String = {&lt;br /&gt;    return """http://ichart.finance.yahoo.com/table.csv?s=""" + ticker +&lt;br /&gt;      "&amp;a="+(start.month.get-1)+ "&amp;b=" + start.day.get + "&amp;c=" + start.year.get +&lt;br /&gt;      "&amp;d="+(end.month.get  -1)+ "&amp;e=" + end.day.get + "&amp;f=" + end.year.get +&lt;br /&gt;      "&amp;g=d&amp;ignore=.csv"&lt;br /&gt;  } &lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;  def main(args : Array[String]) : Unit = {&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    val tickers = &lt;br /&gt;     Source.fromFile(new File("ETFTest.csv")).getLines()&lt;br /&gt;     .drop(1)&lt;br /&gt;     .map(l =&gt; l.trim.split(','))&lt;br /&gt;     .filter(v =&gt; v(2) != "Leveraged")&lt;br /&gt;     .map(values =&gt; (values(0),values(1),values(2),if (values.length==4) values(3) else ""))&lt;br /&gt;     .toSeq.toArray&lt;br /&gt;&lt;br /&gt;    val len = tickers.length;&lt;br /&gt;&lt;br /&gt;    val start = DateTime.now - 2.years&lt;br /&gt;    val end = DateTime.now&lt;br /&gt;    val cevent = new CountDownLatch(len)&lt;br /&gt;    val summaries = new Array[Summary](len)&lt;br /&gt;    &lt;br /&gt;    using(new WebClientConnections(connectionsPerAddress = 10, threadPool=10)) {&lt;br /&gt;      webClientConnections =&gt;&lt;br /&gt;      for (i &lt;- 0 until len) {   &lt;br /&gt;        val t = tickers(i)&lt;br /&gt;        val url = createUrl(t._1, start, end);&lt;br /&gt;        val webClient = webClientConnections.getWebClient&lt;br /&gt;        webClient.DownloadStringCompleted += downloadStringCompleted;&lt;br /&gt;        webClient.DownloadStringAsync(url, (t, cevent, summaries, i));     &lt;br /&gt;      }      &lt;br /&gt;      cevent.await()&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    println&lt;br /&gt;    &lt;br /&gt;    val top15perc =&lt;br /&gt;      summaries&lt;br /&gt;      .filter(s =&gt; s.LRS.isDefined)&lt;br /&gt;      .sortWith((elem1, elem2) =&gt; elem1.LRS &gt;= elem2.LRS)&lt;br /&gt;      .take((len * 0.15).toInt)      &lt;br /&gt;    val bottom15perc =&lt;br /&gt;      summaries&lt;br /&gt;      .filter(s =&gt; s.LRS.isDefined)&lt;br /&gt;      .sortWith((elem1, elem2) =&gt; elem1.LRS &lt;= elem2.LRS)&lt;br /&gt;      .take((len * 0.15).toInt)&lt;br /&gt;&lt;br /&gt;    println&lt;br /&gt;    summaries(0).banner()&lt;br /&gt;    println("TOP 15%")&lt;br /&gt;    for (s &lt;- top15perc) &lt;br /&gt;      s.print() &lt;br /&gt;&lt;br /&gt;    println&lt;br /&gt;    println("Bottom 15%")&lt;br /&gt;    for (s &lt;- bottom15perc) &lt;br /&gt;      s.print()&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def downloadStringCompleted(e : DownloadStringCompletedEventArgs) {&lt;br /&gt;    val bigTuple = e.userState.asInstanceOf[Tuple4[Tuple4[String, String, String, String], CountDownLatch, Array[Summary], Int]]&lt;br /&gt;&lt;br /&gt;    val ((ticker,name,asset,subAsset),cevent,summaries,i) = bigTuple&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    def parse(s : String) = DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime(s);&lt;br /&gt;    &lt;br /&gt;    if (e.error == null) {&lt;br /&gt;      val adjustedPrices =&lt;br /&gt;          e.result&lt;br /&gt;          .split('\n')&lt;br /&gt;          .drop(1)&lt;br /&gt;          .map(l =&gt; l.split(','))&lt;br /&gt;          .filter(l =&gt; l.length == 7)&lt;br /&gt;          .map(v =&gt; Event(parse(v(0)),v(6).toDouble))&lt;br /&gt;&lt;br /&gt;      val timeSeries = new TimeSeries(ticker, name, asset, subAsset, adjustedPrices);&lt;br /&gt;      summaries(i) = timeSeries.getSummary();&lt;br /&gt;      cevent.countDown() &lt;br /&gt;      printf("%s ", ticker)&lt;br /&gt;    } else {&lt;br /&gt;      printf("[%s ERROR] \n", ticker)&lt;br /&gt;      summaries(i) = Summary(ticker,name,"ERROR","ERROR",Some(0),Some(0),Some(0),Some(0),Some(0),0,0,0) &lt;br /&gt;      cevent.countDown()&lt;br /&gt;    }&lt;br /&gt;  }  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/table&gt;&lt;br /&gt;Notes&lt;br /&gt;&lt;br /&gt;TimeSeries getPrice method: Scala does not have output parameters on methods. It doesn't need them because the return type from a method can be a tuple and you can return as many values as you like. Also the method shown copies the C# style closely using loop variables. Another way of writing the same method in Scala making use of list functions is:&lt;br /&gt;&lt;pre class="brush: scala; gutter: false;"&gt;def getPrice(when : DateTime) : Option[(Double,Int)] =  {&lt;br /&gt;  // Find the most recent day with a price starting from when, but don't go back past _start &lt;br /&gt;  val latestDayWithPrice &lt;br /&gt;      = Iterator.iterate(when)(_ - 1.days)&lt;br /&gt;        .dropWhile (d=&gt; !_adjDictionary.contains(d) &amp;&amp; d &gt;= _start )&lt;br /&gt;        .next&lt;br /&gt;  if (_adjDictionary.contains(latestDayWithPrice)) {&lt;br /&gt;    val shift = Days.daysBetween(when,latestDayWithPrice).getDays()&lt;br /&gt;    val aPrice = _adjDictionary(latestDayWithPrice) &lt;br /&gt;    Some((aPrice,shift))&lt;br /&gt;  } else {&lt;br /&gt;    None&lt;br /&gt;  }&lt;br /&gt;}  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;TimeSeries getReturn method: The 2 calls to getPrice() return an Option[a price, days offset].&lt;br /&gt;Dealing with Option[...] in a for expression is an easy way of dealing with the possibilty of either Option[...] being None. If either getPrice() call returns None, then the yield will return a None as well. Another perhaps simpler to understand getReturn implementation is:&lt;br /&gt;&lt;pre class="brush: scala; gutter: false;"&gt;def getReturn(start: DateTime, end: DateTime) : Option[Double] = {&lt;br /&gt;  var endPriceDetails = getPrice(end)&lt;br /&gt;  if (endPriceDetails == None) return None&lt;br /&gt;  val (endPrice,daysBefore) = endPriceDetails.getOrElse(null)&lt;br /&gt;  val startPriceDetails = getPrice(start + daysBefore.days)&lt;br /&gt;  if (startPriceDetails == None) return None&lt;br /&gt;  val (startPrice,_) = startPriceDetails.getOrElse(null)&lt;br /&gt;  (endPrice / startPrice - 1.0)      &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;TimeSeries mav200 method: The scala version is slightly harder work than .net 3.5 LINQ OrderByDescending method with key selector syntax: .OrderByDescending(k =&gt; k.Key). The Scala version has to say *how* to do it. The LINQ version says *what* is required. The same is true for the C# use of the average function, which uses a field selector.&lt;br /&gt;&lt;br /&gt;I'm not happy that I know whether the concurrent access to summaries array access in downloadStringCompleted is safe. It seems to work but I don't know if it is genuinely thread safe. I've just copied the C# code, which may have built-in thread safe array access. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Some of the features of Scala that are shown here&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Easy Java library interop. See use of CountDownLatch, Days, File.&lt;/li&gt;&lt;li&gt;Good old fashioned casting if you really need it. See asInstanceOf.&lt;/li&gt;&lt;li&gt;No semicolons&lt;/li&gt;&lt;li&gt;No need to use () for  a function declaration with no parameters or a call to ut. See TimeSeries.getSummary(). (brackets recommended if there are side effects)&lt;/li&gt;&lt;li&gt;Type declarations are unnecessary except in method parameters, but can be declared explicityly if it aids readability. See _adjDictionary.&lt;/li&gt;&lt;li&gt;Named and default parameters. See WebClientConnections&lt;/li&gt;&lt;li&gt;Much less boilerplate with "case" classes providing automatic constructors, fields, toString, equals, hashcode. See Event, Summary, TimeSeries&lt;/li&gt;&lt;li&gt;Joda time wrapper so you can say "today - 3.years"&lt;/li&gt;&lt;li&gt;Pattern matching assignment "val ((ticker,name),cevent,summaries,i) = bigTuple" in downloadStringCompleted &lt;/li&gt;&lt;li&gt;"using" block for automatic resource closing. In the main method, the "using(new WebClientConnections(" block will close down the WebClientConnections thread pool at the end of the block. This is very similar to the C# "using" code. &lt;/li&gt;&lt;li&gt;local "implicit" function definitions allowing you to effectively add methods to existing classes in a tightly controlled and scoped way. (see def iterableWithSumAndAverage)&lt;/li&gt;&lt;li&gt;Pattern matching, switch on steroids. See todayPrice().&lt;/li&gt;&lt;li&gt;Use of powerful list manipulation functions, such as Iterator.iterate, takeWhile to replace traditional state based loops. See iterate/dropWhile examples in stdDev() and in main(): drop, map, filter, sortWith, take. See the infamous foldLeft example at work in the sum function.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-3578196186974842880?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/3578196186974842880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=3578196186974842880' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3578196186974842880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3578196186974842880'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/10/becoming-really-rich-with-scala.html' title='Becoming really rich with Scala'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-8300067913091893250</id><published>2009-10-19T18:15:00.000-07:00</published><updated>2009-10-20T12:36:47.175-07:00</updated><title type='text'>Checking how to use blogger for side by side code comparison</title><content type='html'>I had to change the Blogger HTML template to do this.&lt;br /&gt;&lt;pre class="brush: plain; gutter: false;"&gt;.post {&lt;br /&gt;padding-$startSide:0%;&lt;br /&gt;padding-$endSide:0%;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;pre class="brush: scala; gutter: false;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;object Primes {&lt;br /&gt;&lt;br /&gt;def primes = {&lt;br /&gt;  def sieve(is: Stream[Int]): Stream[Int] = is match { &lt;br /&gt;case p #:: xs =&amp;gt; p #:: sieve(for (x &amp;lt;- xs if x % p &amp;gt; 0) yield x)&lt;br /&gt;}&lt;br /&gt;sieve(Stream from 2)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def main(args: Array[String]) {&lt;br /&gt;primes take 100 foreach println&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;&lt;br /&gt;&lt;pre class="brush: scala; gutter: false;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;object Primes {&lt;br /&gt;&lt;br /&gt;def primes = {&lt;br /&gt;def sieve(is: Stream[Int]): Stream[Int] = is match { &lt;br /&gt;case p #:: xs =&amp;gt; p #:: sieve(for (x &amp;lt;- xs if x % p &amp;gt; 0) yield x)&lt;br /&gt;}&lt;br /&gt;sieve(Stream from 2)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def main(args: Array[String]) {&lt;br /&gt;primes take 100 foreach println&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-8300067913091893250?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/8300067913091893250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=8300067913091893250' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8300067913091893250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8300067913091893250'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/10/object-primes-haskell.html' title='Checking how to use blogger for side by side code comparison'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-1053480774621696059</id><published>2009-10-13T18:40:00.000-07:00</published><updated>2009-10-14T03:49:35.083-07:00</updated><title type='text'>Scala, lazy evaluation and the Sieve of Eratosthenes</title><content type='html'>I found a Scala algorithm for the Sieve of Eratosthenes &lt;a href="http://louisbotterill.blogspot.com/2009/07/scala-lazy-evaluation-and-sieve-of.html"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Since that was written, the #:: object has been added to Stream and can be used instead of Stream.cons. Also as of a recent nightly build, #:: now object works in Stream pattern matching which means the Sieve of Eratosthenes can be even closer to the haskell implementation. (Presumably a good thing as it broadens your choices)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;object Primes {&lt;br /&gt; &lt;br /&gt;  /* Haskell...&lt;br /&gt;  primes = sieve [2..]&lt;br /&gt;  sieve (p : xs) = p : sieve [x | x &lt;− xs, x `mod` p &gt; 0]&lt;br /&gt;  */ &lt;br /&gt; &lt;br /&gt;  def primes = {&lt;br /&gt;    def sieve(is: Stream[Int]): Stream[Int] = is match { &lt;br /&gt;      case p #:: xs =&gt; p #:: sieve(for (x &lt;- xs if x % p &gt; 0) yield x)&lt;br /&gt;    }&lt;br /&gt;    sieve(Stream from 2)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    primes take 100 foreach println&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Nice!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-1053480774621696059?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/1053480774621696059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=1053480774621696059' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/1053480774621696059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/1053480774621696059'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/10/scala-lazy-evaluation-and-sieve-of.html' title='Scala, lazy evaluation and the Sieve of Eratosthenes'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-3406161341581946302</id><published>2009-10-13T15:50:00.000-07:00</published><updated>2009-10-15T14:28:00.295-07:00</updated><title type='text'>Scala Streams for iteration / Use streams to avoid TCO(?)</title><content type='html'>&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;My last post &lt;a href="http://quoiquilensoit.blogspot.com/2009/10/scala-c-style-iterate-function-for.html"&gt;Scala: C style iterate function for building lists&lt;/a&gt; got an amazing response from somebody called Johan. (Thanks Johan). It introduced me to the amazing power of lazy scala streams.&lt;br /&gt;&lt;br /&gt;Here's what Johan said slightly edited (In Johan's comment, he used lazy_:: which is now called #:: in Scala 2.8):&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;[Your iterateFor] function is very similar to until (but with a reversed predicate) in Haskell: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3Auntil. Basically, it's iterate and takeWhile.&lt;br /&gt;&lt;br /&gt;Unfortunately, the iterate functions in Scala's traversable collections are not polymorphic. (Maybe it's because it would only work for lazy collections.) But here's one for Stream:&lt;br /&gt;&lt;br /&gt;def iterate[A](step: A =&gt; A)(seed: A): Stream[A] = seed #:: iterate(step)(step(seed))&lt;br /&gt;&lt;br /&gt;Now it's easy to write iterateFor:&lt;br /&gt;&lt;br /&gt;def iterateFor[A](predicate: A =&gt; Boolean)(step: A =&gt; A)(seed: A): Stream[A] = iterate(step)(seed) takeWhile predicate&lt;br /&gt;&lt;br /&gt;or, all in one go:&lt;br /&gt;&lt;br /&gt;def until[A](...) = if (!predicate(seed)) seed #:: until(predicate)(step)(step(seed)) else Stream.empty&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Now the symbol #:: is a special lazy "cons" operator for Streams (used just like the List :: operator) which only gets evaluated on demand. The #:: operator can be used to define infinite lists as Johan has done with the iterate function. &lt;br /&gt;&lt;br /&gt;Now before I get on to trying this stuff out, the way Johan defined the functions, you need to specify the type of [A] when you call them, for example iterate[Int].... But if you move the seed parameter from the last parameter to the first then you can get away with not defining A explicitly. So here are the functions reorganized to make them easier to use:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;  def iterate[A]&lt;br /&gt;      (seed: A)(step: A =&gt; A)&lt;br /&gt;      : Stream[A] &lt;br /&gt;      = seed #:: iterate(step(seed))(step)&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;  def iterateFor[A] (seed: A)(predicate: A =&gt; Boolean)(step: A =&gt; A)&lt;br /&gt;      : Stream[A] &lt;br /&gt;      = iterate(seed)(step) takeWhile predicate&lt;br /&gt;      &lt;br /&gt;  def until[A] &lt;br /&gt;      (seed: A)(predicate: A =&gt; Boolean)(step: A =&gt; A) &lt;br /&gt;      : Stream[A] &lt;br /&gt;      = if (!predicate(seed)) seed #:: until(step(seed))(predicate)(step) else Stream.empty&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So what can I do with all this ****? Well first of all, iterate defines an infinite list, that is evaluated as needed so the following loop will iterate forever &lt;span style="font-style:italic;"&gt;printing as it goes&lt;/span&gt;, &lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;for (i &lt;- iterate(0)(_ + 1)) {&lt;br /&gt;  println(i)&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;as will &lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;iterate(0)(_ + 1).foreach(println)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that I said &lt;span style="font-style:italic;"&gt;printing as it goes&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If you defined iterator using List instead of Stream replacing #:: with :: , then the loops above would get a StackOverflowError after munching stack on each iteration, but also, nothing would be printed, as the entire (infinite) List is calculated before anything is printed.&lt;br /&gt;&lt;br /&gt;So what use is the iterate function using Streams? Well you can reinvent a convoluted for loop, by taking the first n of the infinite stream. &lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;  for (i &lt;- iterate(0)(_ + 1) take 10 ) {&lt;br /&gt;    println(i)&lt;br /&gt;  }   &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Big deal, but more importantly its a building block: Johan went on to redefine my original iterateFor function (see the last post) using iterator and takeWhile.&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;def iterateFor[A] (seed: A)(predicate: A =&gt; Boolean)(step: A =&gt; A)&lt;br /&gt;    : Stream[A] &lt;br /&gt;    = iterate(seed)(step) takeWhile predicate&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;How simple is that! &lt;br /&gt;&lt;br /&gt;As he also pointed out iterateFor can be defined without iterate like this:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;    def iterateFor[A](seed: A)(predicate: A =&gt; Boolean)(step: A =&gt; A) : Stream[A] &lt;br /&gt;        = if (predicate(seed)) seed #:: iterateFor(step(seed))(predicate)(step) else Stream.empty&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;except that he called that version "until" to match the haskell function. I don't like this name for two reasons in scala: (1) "until" is already used in "for (i &lt;- 1 until 10)" and (2) by moving the seed parameter to the first parameter (as I explained above), until(0)(_ &gt;= 10)(_ + 1) does not read well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;A Reminder About What This Is All For!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;iterateFor is not for counting from 1 to 10! Use the normal Scala for (i &lt;- 1 to 10) for that!&lt;br /&gt;&lt;br /&gt;This is what I originally wanted it for:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;val dates = iterateFor(today)(d =&gt; d &gt;= _start &amp;&amp; d &gt;= limit)(d =&gt; d - 7.days)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;The elephants in the room&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Stack? These lazy stream versions of iterateFor DO NOT munch stack even though they do not look like they can be TCO'd. Amazing. I don't understand how it works, but it does. Maybe they munch alot more heap . Who knows.&lt;br /&gt;&lt;br /&gt;2. Performance. I have not studied this in detail, but from what I have found with some simple (and probably flawed) tests, there is NO performance penalty. The use of streams in this way seems to be at least as fast as the TCOd recursive algorithms and the imperative while algorithm.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-3406161341581946302?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/3406161341581946302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=3406161341581946302' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3406161341581946302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3406161341581946302'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/10/scala-streams-for-iteration-use-streams.html' title='Scala Streams for iteration / Use streams to avoid TCO(?)'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-5240976571360820094</id><published>2009-10-12T14:11:00.000-07:00</published><updated>2009-10-15T02:43:56.618-07:00</updated><title type='text'>Scala: C style iterate function for building lists</title><content type='html'>In my previous post, I used a forloop function for creating a List from a sort of c-like for loop&lt;br /&gt;&lt;pre class='brush: scala'&gt;&lt;br /&gt;    val rets = forloop(today)(d =&gt; d &gt;= _start &amp;&amp; d &gt;= limit)(d =&gt; d - 7.days) {&lt;br /&gt;     day =&gt; &lt;br /&gt;          val ret = getReturn(day - 7.days, day)&lt;br /&gt;          ret.get // might throw Exception (same as c# code)&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I liked the fact that I could use break and continue semantics in the loop although I didn't need it in the algorithm. &lt;br /&gt;&lt;br /&gt;But perhaps foreach is/was trying to do too much, effectively (a) producing a list of dates (etc) and then (b) for each date in the List calculating another value (a Double) to return in a list. Of course (b) is just the map function. So here's another function that I've called iterateFor which only does (a). Using it to replace the code above gives: &lt;br /&gt;&lt;br /&gt;&lt;pre class='brush: scala'&gt;&lt;br /&gt;    val dates = iterateFor(today)(d =&gt; d &gt;= _start &amp;&amp; d &gt;= limit)(d =&gt; d - 7.days)&lt;br /&gt;    val rets = dates.map(d =&gt; getReturn(d - 7.days, d).get)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I was hoping to find something already built it to the scala libraries that would do what iterateFor does . As Daniel pointed out in the comments there is Iterator.iterate:&lt;br /&gt;&lt;pre class='brush: scala'&gt;&lt;br /&gt;  def iterate  [T](start : T)(f : (T) =&gt; T) : Iterator[T] &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and if you use takeWhile on the Iterator then the implementation of iterateFor is simple:&lt;br /&gt;&lt;br /&gt;&lt;pre class='brush: scala'&gt;&lt;br /&gt;def iterateFor[T]&lt;br /&gt;  (init: T)&lt;br /&gt;  (cond: T =&gt; Boolean)&lt;br /&gt;  (next: T =&gt; T)&lt;br /&gt;: List[T] = &lt;br /&gt;{&lt;br /&gt;  Iterator.iterate(init)(next) takeWhile cond toList&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or it can be implemented as a recursive function like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class='brush: scala'&gt;&lt;br /&gt;def iterateFor[T]&lt;br /&gt;  (init: T)&lt;br /&gt;  (cond: T =&gt; Boolean)&lt;br /&gt;  (next: T =&gt; T)&lt;br /&gt;: List[T] = &lt;br /&gt;{&lt;br /&gt;  def _iterateFor(currentResults: List[T])(loopcounter: T) : List[T] = {&lt;br /&gt;    if (cond(loopcounter)) {&lt;br /&gt;      val newResults = loopcounter :: currentResults&lt;br /&gt;      _iterateFor(newResults)(next(loopcounter))&lt;br /&gt;    } else {&lt;br /&gt;      currentResults&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  _iterateFor(List())(init).reverse&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I suspect that there are plenty of little while loop type algorithms that use vars that could be replaced by iterateFor (or forloop).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-5240976571360820094?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/5240976571360820094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=5240976571360820094' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/5240976571360820094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/5240976571360820094'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/10/scala-c-style-iterate-function-for.html' title='Scala: C style iterate function for building lists'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-3730534595809344837</id><published>2009-10-09T17:33:00.001-07:00</published><updated>2009-10-15T15:25:38.371-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>C style for loops in Scala with break and continue</title><content type='html'>&lt;span style="font-family:verdana;"&gt;(If you don't want to read about how I ended up hand rolling C style loops in scala then go straight to the end result &lt;a href="http://quoiquilensoit.blogspot.com/2009/10/c-style-for-loops-in-scala-with-break_09.html#final"&gt;here&lt;/a&gt;.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style="font-family: verdana;" href="http://blogs.msdn.com/lucabol/archive/2009/09/22/becoming-really-rich-with-c.aspx"&gt;Becoming really rich with C#&lt;/a&gt;&lt;span style="font-family:verdana;"&gt; is a great example of what's coming in the version of C# in Visual Studio 2010 and it makes it obvious that C# is leaving Java in the dust. That why I'm looking at scala.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;As an excercise, I translated the c# version of the stdDev function into Scala, copying the imperative non-functional style in the original c# code&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;Imperative version of stddev&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="brush: scala"  style="font-family:verdana;"&gt;  // 1 for 1 translation of imperative c# version&lt;br /&gt;def stdDevImperative(): Double = {&lt;br /&gt;  var now = Dates.now()&lt;br /&gt;  val limit = now - 3.years&lt;br /&gt;  var rets = List[Double]()&lt;br /&gt;  while (now &gt;= _start + 12.days &amp;amp;&amp;amp; now &gt;= limit) {&lt;br /&gt;    val ret = getReturn(now - 7.days, now);&lt;br /&gt;    val retd = ret.get // might throw Exception (same as c# code)&lt;br /&gt;    rets = rets ::: retd :: Nil&lt;br /&gt;    now = now - 7.days;&lt;br /&gt;  }&lt;br /&gt;  val mean = average(rets)&lt;br /&gt;  val variance = sum(rets.map(r =&gt; Math.pow(r - mean, 2))) / rets.length&lt;br /&gt;  val weeklyStdDev = Math.sqrt(variance)&lt;br /&gt;  return weeklyStdDev * Math.sqrt(40)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Couple of notes here. I'm using the joda time scala wrapper (import org.scala_tools.time.Imports._). The sum() and average() functions should be  obvious. getReturn(now - 7.days, now) returns an Option[Double] of the increase in price in the last seven days as per the c# version.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;&lt;table border='1'&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;&lt;br&gt;&lt;span style="font-weight:bold;"&gt;If you are learning Scala, you can stop right here! The imperative version shown above is absolutely fine. What follows here is an intellectual exercise in using functional programming techniques to reorganize the algorithm so that it does not use vars. Many people would see this as a pointless exercise. &lt;br&gt;&lt;br&gt;&lt;br /&gt;It also turns out that there is a very simple solution to this exercise which is described in the follow up section at the end of the post. &lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;I wanted to convert my stdDevImperative to a functional style, getting rid of all those icky vars. So this was my first go:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Simple Recursive version of stddev&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala" face="verdana"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;font-family:verdana;" &gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;// simplistic recursive version of imperative c# version&lt;br /&gt;def stdDevSimpleRecursive(): Double = {&lt;br /&gt;  var now = Dates.now()&lt;br /&gt;  val limit = now - 3.years&lt;br /&gt;  def getListOfReturns(d : DateTime) : List[Double] = {&lt;br /&gt;    if (d &gt;= _start + 12.days &amp;amp;&amp;amp; d &gt;= limit)&lt;br /&gt;      getReturn(d - 7.days, d).get :: getListOfReturns(d - 7.days) // Not TCO&lt;br /&gt;    else&lt;br /&gt;      Nil&lt;br /&gt;  }&lt;br /&gt;  val rets = getListOfReturns(now)&lt;br /&gt;  val mean = average(rets)&lt;br /&gt;  val variance = sum(rets.map(r =&gt; Math.pow(r - mean, 2))) /rets.length&lt;br /&gt;  val weeklyStdDev = Math.sqrt(variance);&lt;br /&gt;  return weeklyStdDev * Math.sqrt(40);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;No more vars, but its longer and the algorithm is less obvious than the imperative version. (At least for me). Also the compiler cannot perform "tail call optimisation". And so it munches stack.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Next step: allow the compiler to use "tail call optimisation".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;TCO Recursive version of stddev&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: verdana;" class="brush: scala"&gt;&lt;br /&gt;  // recursive version allowing TCO and insert result at head of list&lt;br /&gt;  def stdDevTCORecursive(): Double = {&lt;br /&gt;    var now = Dates.now()&lt;br /&gt;    val limit = now - 3.years&lt;br /&gt;    def getListOfReturns(results: List[Double], d : DateTime) : List[Double] = {&lt;br /&gt;      if (d &gt;= _start + 12.days &amp;&amp; d &gt;= limit) {&lt;br /&gt;        val newResults = getReturn(d - 7.days, d).get :: results // optimised to add to head not tail  &lt;br /&gt;        getListOfReturns(newResults, d - 7.days) // TCO possible&lt;br /&gt;      } else&lt;br /&gt;        results&lt;br /&gt;    }&lt;br /&gt;    val rets = getListOfReturns(List(),now).reverse // reverse unnecessary for algorithm, but matches c# ordering&lt;br /&gt;    val mean = average(rets)&lt;br /&gt;    val variance = sum(rets.map(r =&gt; Math.pow(r - mean, 2))) /rets.length&lt;br /&gt;    val weeklyStdDev = Math.sqrt(variance);&lt;br /&gt;    return weeklyStdDev * Math.sqrt(40);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Well it works, but its getting uglier and the actual algorithm is being obscured. (Yeah I know, premature optimisation is the root of all evil. Yada. But TCO is pretty basic).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;So I got to thinking if there was a better algoirthm and couldn't think of one. All the neat algorithms use a starting list/sequence and I couldn't see one. We are going back in time 7 days at a time, stoping when we get to the first date (_start) of the available price history or we have collected 3 years worth of returns. Hell, I liked the imperative algorithm. Maybe that will change with as my brain adapts to functional techniques. I though what I need is a way of factoring out the recursion into a "thing".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Enter the &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://scala-blogs.org/2008/01/roman-numerals-in-scala.html"&gt;unfold&lt;/a&gt;&lt;span style="font-family:verdana;"&gt; function described nicely by David Pollak. I though that this might be the solution. So here goes:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Unfold version of stddev&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: verdana;" class="brush: scala"&gt;&lt;br /&gt;// This unfold function should probably be built into a scala standard library somewhere&lt;br /&gt;def unfold[T, R](init: T)(f: T =&gt; Option[(R, T)]): List[R] = f(init) match {&lt;br /&gt;  case None =&gt; Nil&lt;br /&gt;  case Some(r, v) =&gt; r :: unfold(v)(f)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def stdDevUnfold(): Double = {&lt;br /&gt;  val now = Dates.now()&lt;br /&gt;  val limit = now - 3.years&lt;br /&gt;  def getReturnOnDayAndNextDay(someDay: DateTime) : Option[(Double, DateTime)] = {&lt;br /&gt;    if (someDay &lt; _start || someDay &lt; limit) return None&lt;br /&gt;    val ret = getReturn(someDay - 7.days, someDay)&lt;br /&gt;    Some((ret.get, someDay - 7.days)) // might throw Exception (same as c# code)&lt;br /&gt;  }&lt;br /&gt;  val rets = unfold(now)(getReturnOnDayAndNextDay)&lt;br /&gt;  val mean = average(rets)&lt;br /&gt;  val variance = sum(rets.map(r =&gt; Math.pow(r - mean, 2)))&lt;br /&gt;  val weeklyStdDev = Math.sqrt(variance / rets.length);&lt;br /&gt;  return weeklyStdDev * Math.sqrt(40);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;So the recursion is now out of my stdDev function but the code is even more obscure. The problem is that the unfold parameter function f() has two jobs to do. (1) manage a loop counter, (in this case the current date) and (2) return a value to be collected in the returned results.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;So I liked the &lt;/span&gt;&lt;span style="font-style: italic;font-family:verdana;" &gt;idea&lt;/span&gt;&lt;span style="font-family:verdana;"&gt; of unfold because it hides the recursion, but not the multiple jobs that the function has to do. The obvious answer is to have more than one function argument: One function to get the next value for the iteration or terminate and another function that works out the result. Hang on a minute, that first function is doing two jobs: getting the next value and working out when to terminate. How about three functions? Hey wait while we're there...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;This is what I see in my head as the clearest way of defining the algorithm in a sort of java/pseudocode&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: verdana;" class="brush: java"&gt;&lt;br /&gt;// Java like pseudocode&lt;br /&gt;ArrayList a = new ArrayList();&lt;br /&gt;for (DateTime d = today(); d &gt; firstDateForWhichPriceIsAvaialble &amp;amp;&amp;amp; d &gt; today - 3.years; d = d - 7.days) {&lt;br /&gt;  a.append(getReturn(d, d-7.days));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:verdana;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;&lt;a name="final"&gt;Final version of stddev with forloop&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;The challenge was to come up with something completely stateless of course. After many iterations (ha ha) this is what I have ended up with as my new stdDev method:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: verdana;" class="brush: scala"&gt;&lt;br /&gt;def stdDevForLoop(): Double = {&lt;br /&gt;  val today = Dates.now()&lt;br /&gt;  val limit = today - 3.years&lt;br /&gt;  val rets =&lt;br /&gt;    forloop(today)(d =&gt; d &gt;= _start &amp;amp;&amp;amp; d &gt;= limit)(d =&gt; d - 7.days) {&lt;br /&gt;      day =&gt;&lt;br /&gt;        val ret = getReturn(day - 7.days, day)&lt;br /&gt;        ret.get // might throw Exception (same as c# code)&lt;br /&gt;    }&lt;br /&gt;  val mean = average(rets)&lt;br /&gt;  val variance = sum(rets.map(r =&gt; Math.pow(r - mean, 2))) / rets.length&lt;br /&gt;  val weeklyStdDev = Math.sqrt(variance);&lt;br /&gt;  return weeklyStdDev * Math.sqrt(40);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;I was pretty happy with the result, which, to my non-functional brain, expresses the algorithm (slightly) more clearly than the original imperative algorithm but without using any vars. The recursion is neatly tucked away in the forloop method.  The definition of forloop is shown at the end.&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:verdana;font-size:130%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:verdana;font-size:130%;"  &gt;The icing on the cake: break and continue&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;I realised that c style break and continue would be relatively easy to implement copying the techniques used in &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://www.slideshare.net/Odersky/fosdem-2009-1013261"&gt;breakable&lt;/a&gt;&lt;span style="font-family:verdana;"&gt;. As ever the devil is in the detail: as the forloop body yields a value that is collected in the list of results, I added a breakWith 'keyword' too so that you can return a last value when you break. So the following becomes possible:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: verdana;" class="brush: scala"&gt;&lt;br /&gt;def stdDevForLoopBreakAndContinue(): Double = {&lt;br /&gt;  val today = Dates.now()&lt;br /&gt;  val limit = today - 3.years&lt;br /&gt;  val rets = forloop(today)(d =&gt; d &gt;= _start &amp;amp;&amp;amp; d &gt;= limit)(d =&gt; d - 7.days) {&lt;br /&gt;    day =&gt;&lt;br /&gt;      val ret = getReturn(day - 7.days, day)&lt;br /&gt;      if (day == blackFriday1981) continue&lt;br /&gt;      if (day == blackWednesday1973) breakWith(0d) // or just plain break, if no final value required&lt;br /&gt;      ret.get // might throw Exception (same as c# code)&lt;br /&gt;  }&lt;br /&gt;  val mean = average(rets)&lt;br /&gt;  val variance = sum(rets.map(r =&gt; Math.pow(r - mean, 2))) / rets.length&lt;br /&gt;  val weeklyStdDev = Math.sqrt(variance);&lt;br /&gt;  return weeklyStdDev * Math.sqrt(40);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=";font-family:verdana;font-size:130%;"  &gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's missing?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li style="font-family: verdana;"&gt;Multiple loop counters. Of course you can do this by using a Tuple as the loop counter containing  as many 'embedded' loop counters as you need, but this gets Lispy with the brackets. Maybe there is a nicer way.&lt;/li&gt;&lt;/ul&gt;&lt;span style=";font-family:verdana;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;Here's the code for forloop:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="'brush: scala"&gt;&lt;br /&gt;&lt;br /&gt;trait ForLoops&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def forloop[T, R]&lt;br /&gt;    (init: T)&lt;br /&gt;    (cond: T =&gt; Boolean)&lt;br /&gt;    (next: T =&gt; T)&lt;br /&gt;    (body: T =&gt; R)&lt;br /&gt;    : List[R] = &lt;br /&gt;  {&lt;br /&gt;    def _forloop(currentResults: List[R])(loopcounter: T) : List[R] = {&lt;br /&gt;      if (cond(loopcounter)) {&lt;br /&gt;        // Get the newResults by appending the result of the body() function on the current loopcounter&lt;br /&gt;        val newResults = try {&lt;br /&gt;          // normal case: body() returns something based on loopcounter&lt;br /&gt;          val bodyResult = body(loopcounter)&lt;br /&gt;          &lt;br /&gt;          bodyResult match {&lt;br /&gt;           // if the body has no return value (Unit) then don't bother appending to the newResults&lt;br /&gt;           case _:Unit =&gt; currentResults&lt;br /&gt;           // if the body has a return value then append to the newResults&lt;br /&gt;           case _ =&gt; bodyResult :: currentResults&lt;br /&gt;          }&lt;br /&gt;          &lt;br /&gt;        } catch {&lt;br /&gt;          case ex: ContinueException =&gt; currentResults     // don't add to the currentResults&lt;br /&gt;          case ex: BreakException =&gt; return currentResults // exit loop so return currentResults&lt;br /&gt;          case BreakWithException(v) =&gt; return v.asInstanceOf[R] :: currentResults &lt;br /&gt;        }&lt;br /&gt;        // This can be tail call optimized&lt;br /&gt;        // Recursive call to loop with the next value of the loop counter&lt;br /&gt;        _forloop(newResults)(next(loopcounter))&lt;br /&gt;      } else {&lt;br /&gt;        // loop has terminated so return results&lt;br /&gt;        currentResults&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    // Seed the _forloop currentResults with an empty list and the first value (init) of the loopcounter&lt;br /&gt;    _forloop(List())(init).reverse&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // Copied break and continue technique from "breakable" in Scala 2.8    &lt;br /&gt;  def continue = throw continueException&lt;br /&gt;  def break = throw breakException&lt;br /&gt;  def breakWith(v:Any) = throw new BreakWithException(v)&lt;br /&gt;&lt;br /&gt;  private class ContinueException extends RuntimeException&lt;br /&gt;  private val continueException = new ContinueException &lt;br /&gt;&lt;br /&gt;  private class BreakException extends RuntimeException&lt;br /&gt;  private val breakException = new BreakException &lt;br /&gt;&lt;br /&gt;  private case class BreakWithException(v:Any) extends RuntimeException {&lt;br /&gt;    override def fillInStackTrace():Throwable =  {&lt;br /&gt;      // this is a performance optimisation. the actual stack trace is not required.&lt;br /&gt;      return null;&lt;br /&gt;    }       &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:verdana;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;Follow up: An implementation using Iterator.iterate:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;In the next couple of posts (in the future) I look at various alternatives to the forloop function that I have described above and got some very helpful comments from various people. The simplest (and built-in) solution that I found was using the new Iterator.iterate method in Scala 2.8pre along with takeWhile and map. Also, a very neat alternative to Iterator.iterate is to use define an &lt;a href="http://quoiquilensoit.blogspot.com/2009/10/scala-streams-for-iteration-use-streams.html "&gt;iterate method that uses lazy Stream&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;&lt;pre class="'brush: scala"&gt;&lt;br /&gt;&lt;br /&gt;  def stdDevIteratorIterate(): Double = {&lt;br /&gt;    val today = Dates.now()&lt;br /&gt;    val limit = today - 3.years&lt;br /&gt;    val dates = Iterator.iterate(today)(_ - 7.days) takeWhile (d =&gt; d &gt;= _start &amp;&amp; d &gt;= limit) toList&lt;br /&gt;    val rets = dates.map(d =&gt; getReturn(d - 7.days, d).get)&lt;br /&gt;    val mean = rets.average&lt;br /&gt;    val variance = rets.map(r =&gt; Math.pow(r - mean, 2)).average&lt;br /&gt;    val weeklyStdDev = Math.sqrt(variance);&lt;br /&gt;    return weeklyStdDev * Math.sqrt(40);&lt;br /&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/6818189468244276547-3730534595809344837?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/3730534595809344837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=3730534595809344837' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3730534595809344837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3730534595809344837'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/10/c-style-for-loops-in-scala-with-break_09.html' title='C style for loops in Scala with break and continue'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-3444204777616274201</id><published>2009-10-09T14:37:00.000-07:00</published><updated>2009-10-17T16:28:51.294-07:00</updated><title type='text'>Using syntax version of SyntaxHighlighter with Blogger</title><content type='html'>The latest version 2.1.364 of the amazing &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;SyntaxHighlighter&lt;/a&gt; from Alex Gorbatchev needs a bit of TLC to get working on Blogger:&lt;br /&gt;&lt;br /&gt;Below is what I have right before the &amp;lt;/head&amp;gt; tag in the Edit HTML tab of my Blogger layout.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: html"&gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shCore.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCSharp.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushJava.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushJScript.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushPlain.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushScala.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushXml.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shCore.css' rel='stylesheet' type='text/css'/&amp;gt;&lt;br /&gt;&amp;lt;link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shThemeDefault.css' id='shTheme' rel='stylesheet' type='text/css'/&amp;gt;&lt;br /&gt;&amp;lt;style type='text/css'&amp;gt;&lt;br /&gt;.syntaxhighlighter .line {&lt;br /&gt;font-size: 76% !important;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script type='text/javascript'&amp;gt;&lt;br /&gt;SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.1.364/scripts/clipboard.swf';&lt;br /&gt;SyntaxHighlighter.all();&lt;br /&gt;SyntaxHighlighter.config.bloggerMode=true;&lt;br /&gt;SyntaxHighlighter.defaults['font-size'] = '50%';&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Thats all you need to make it work.&lt;br /&gt;&lt;br /&gt;The ugly section&lt;br /&gt;&lt;pre class="brush: html"&gt;&lt;br /&gt;&amp;lt;style type='text/css'&amp;gt;&lt;br /&gt;.syntaxhighlighter .line {&lt;br /&gt;font-size: 76% !important;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;works around a bug in this version of SyntaxHighlighter described &lt;a href="http://alexgorbatchev.com/forums/comments.php?DiscussionID=67&amp;amp;page=1#Item_0"&gt;here&lt;/a&gt;. This allows SyntaxHighlighter.defaults['font-size'] = '50%'; to actually have an effect. If you don't do this, for some reason the code is shown at a ridiculously large size.&lt;br /&gt;&lt;br /&gt;So now I can type exactly what you see here into Blogger's Compose editor&lt;br /&gt;&lt;pre class="brush: html"&gt;&lt;br /&gt;&amp;lt;pre class="brush: scala"&amp;gt;&lt;br /&gt;   def factorialInt(i: Int): Int = {&lt;br /&gt;     def fact(i: Int)(accumulator: Int): Int = i match {&lt;br /&gt;       case 1 =&amp;gt; accumulator&lt;br /&gt;       case _ =&amp;gt; fact(i - 1)(i * accumulator)&lt;br /&gt;     }&lt;br /&gt;     fact(i)(1)&lt;br /&gt;   }  &lt;br /&gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;which then appears as follows&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;   def factorialInt(i: Int): Int = {&lt;br /&gt;     def fact(i: Int)(accumulator: Int): Int = i match {&lt;br /&gt;       case 1 =&gt; accumulator&lt;br /&gt;       case _ =&gt; fact(i - 1)(i * accumulator)&lt;br /&gt;     }&lt;br /&gt;     fact(i)(1)&lt;br /&gt;   }  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There is a newer syntax as of 2.1.364 which uses CDATA section for your code which allows you to put special charcters such as &lt; and &gt; characters directly in the code without them being encoded as &amp;amp;lt; or &amp;amp;gt; which is possibly useful for Scala. Although blogger does this for you (automatic encoding of special characters) so its not too important for blogger posts.&lt;br /&gt;&lt;br /&gt;So if you type exactly what you see here into Blogger's Compose editor (but the "pre" syntax above is simpler when using blogger&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: html"&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: scala"&gt;&amp;lt;![CDATA[&lt;br /&gt;   def factorialInt(i: Int): Int = {&lt;br /&gt;     def fact(i: Int)(accumulator: Int): Int = i match {&lt;br /&gt;       case 1 =&gt; accumulator&lt;br /&gt;       case _ =&gt; fact(i - 1)(i * accumulator)&lt;br /&gt;       // &lt; &gt;&lt;br /&gt;     }&lt;br /&gt;     fact(i)(1)&lt;br /&gt;   }  &lt;br /&gt;]]&gt;&lt;/script&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;then you get this&lt;br /&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: scala"&gt;&lt;![CDATA[&lt;br /&gt;   def factorialInt(i: Int): Int = {&lt;br /&gt;     def fact(i: Int)(accumulator: Int): Int = i match {&lt;br /&gt;       case 1 =&gt; accumulator&lt;br /&gt;       case _ =&gt; fact(i - 1)(i * accumulator)&lt;br /&gt;       // &lt; &gt;&lt;br /&gt;     }&lt;br /&gt;     fact(i)(1)&lt;br /&gt;   }  &lt;br /&gt;]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-3444204777616274201?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/3444204777616274201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=3444204777616274201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3444204777616274201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/3444204777616274201'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/10/using-syntax-version-of.html' title='Using syntax version of SyntaxHighlighter with Blogger'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-938990032581859769</id><published>2009-09-16T15:18:00.000-07:00</published><updated>2009-09-16T15:38:54.290-07:00</updated><title type='text'>Ubuntu 9.04 remote xdmcp on ctrl-alt-f9</title><content type='html'>See also http://ubuntuguide.org/wiki/Ubuntu:Feisty/RemoteAccess#What_is_XDMCP.3F&lt;br /&gt;&lt;br /&gt;Ctrl-Alt-F1&lt;br /&gt;login&lt;br /&gt;X :1 -query 192.168.1.12&lt;br /&gt;Should get login prompt on remote machine&lt;br /&gt;Ctrl-Alt-F7 to switch back to local login&lt;br /&gt;Ctrl-Alt-F9 to switch to remote login&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-938990032581859769?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/938990032581859769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=938990032581859769' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/938990032581859769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/938990032581859769'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/09/ubuntu-904-remote-xdmcp-on-ctrl-alt-f9.html' title='Ubuntu 9.04 remote xdmcp on ctrl-alt-f9'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-918552227478600506</id><published>2009-09-06T14:07:00.000-07:00</published><updated>2009-09-06T14:18:50.662-07:00</updated><title type='text'>Convert various phone video to DVD in linux</title><content type='html'>Problem: Various .MOV and .AVI files in various small resolutions collected over the years. How do you to convert to dvd?&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;br /&gt;Ubuntu 9.04&lt;br /&gt;&lt;br /&gt;Used WinFF aka "Video Converter" front end to mpeg&lt;br /&gt;&lt;br /&gt;In WinFF, I dragged and dropped all the avi and mov files to WinDD.&lt;br /&gt;&lt;br /&gt;In WinFF,Then I selected the “Output Details” and picked “Convert to: DVD”. “Device Preset” PAL DVD HQ (16:9)&lt;br /&gt;&lt;br /&gt;WinFF used this command &lt;br /&gt;/usr/bin/ffmpeg -threads 2 -i "/media/2004-07-23/VideosFromCamera/2003-08-02_0845_100_0088.avi" -target pal-dvd -aspect 16:9 -b 8000k -mbd rd -trellis -mv0 -cmp 0 -subcmp 2 "/media/2004-07-23/VideosFromCameraConverted/2003-08-02_0845_100_0088.mpg"&lt;br /&gt;&lt;br /&gt;(WinFF "Edit-Preferences-Multithreading for dual core" gives the "-threads 2" option)&lt;br /&gt;&lt;br /&gt;Next step, create the DVD structure (see the end for an example dvd.xml file which you need to edit to list which movies to include on the DVD):&lt;br /&gt;&lt;br /&gt;dvdauthor -o dvd -x dvd.xml&lt;br /&gt;&lt;br /&gt;Check it worked with&lt;br /&gt;&lt;br /&gt;mplayer dvd:// -dvd-device ./dvd&lt;br /&gt;&lt;br /&gt;Burn the DVD with&lt;br /&gt;&lt;br /&gt;growisofs -dvd-compat -Z /dev/dvdrw -dvd-video ./dvd/&lt;br /&gt;Example dvd.xml file used by dvdauthor above:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;dvdauthor&amp;gt;&lt;br /&gt;  &amp;lt;vmgm /&amp;gt;&lt;br /&gt;  &amp;lt;titleset&amp;gt;&lt;br /&gt;    &amp;lt;titles&amp;gt;&lt;br /&gt;      &amp;lt;video format="pal" aspect="4:3"/&amp;gt;&lt;br /&gt;      &amp;lt;audio format="ac3" lang="en"/&amp;gt;&lt;br /&gt;      &amp;lt;pgc&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00026.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00027.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00028.mpg"/&amp;gt;&lt;br /&gt;      &amp;lt;/pgc&amp;gt;&lt;br /&gt;    &amp;lt;/titles&amp;gt;&lt;br /&gt;  &amp;lt;/titleset&amp;gt;&lt;br /&gt;&amp;lt;/dvdauthor&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that I used an aspect ratio of 4:3 in the dvd.xml file above which suited the source video from the phones, but 16:9 can be used too. (But when using WinFF I had no success selecting the  “Device Preset” PAL DVD HQ (4:3) option, only the (16:9) option worked ok. With the (4:3) preset, WinFF would work fine, but dvdauthor would generate lots of warnings and the final dvd would not play well)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-918552227478600506?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/918552227478600506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=918552227478600506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/918552227478600506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/918552227478600506'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/09/convert-various-phone-video-to-dvd-in.html' title='Convert various phone video to DVD in linux'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-8656454159385049406</id><published>2009-09-04T05:53:00.000-07:00</published><updated>2009-09-04T06:04:57.587-07:00</updated><title type='text'>HOWTO: Convert and write AVCHD (.mts) to DVD with Linux</title><content type='html'>Inspired by &lt;a href="http://blog.mymediasystem.net/avchd/howto-convert-and-write-avchd-mts-to-dvd-on-linux/"&gt;http://blog.mymediasystem.net/avchd/howto-convert-and-write-avchd-mts-to-dvd-on-linux/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sucessfully converted video from my Panasonic HDC SD20 using these instructions: &lt;p&gt;Using ubuntu 9.04 jaunty.&lt;/p&gt; &lt;p&gt;Connected camera via usb.&lt;/p&gt; &lt;p&gt;Simply copied the AVCHD folder under the top level PRIVATE folder. You actually just need the MTS files in the AVCHD/BDMV/STREAM folder. &lt;/p&gt; &lt;p&gt;I Installed the WinFF (via ubuntu menu Applications/Add&amp;amp;Remove). WinFF is just a front end to ffmpeg. &lt;/p&gt; &lt;p&gt;In WinFF, I dragged and dropped all the MTS files to WinDD. &lt;/p&gt; &lt;p&gt;In WinFF,Then I selected the “Output Details” and picked “Convert to: DVD”. “Device Preset” PAL DVD HQ (16:9). &lt;/p&gt; &lt;p&gt;VERY IMPORTANT: I had to set “Additional Options/Audio Settings/Audio Channels: 2″. Otherwise I got an error on the console when trying to convert: “Error while opening codec for output stream #0.1 – maybe incorrect parameters such as bit_rate, rate, width or height”. &lt;/p&gt; &lt;p&gt;In WinFF, click Convert. Its very very slow: 8 hours per hour of video!&lt;/p&gt; &lt;p&gt;I ended up with one output mpg file per input MTS file.&lt;/p&gt; &lt;p&gt;Next step, create the DVD structure (see the end for an example dvd.xml file which you need to edit to list which movies to include on the DVD):&lt;br /&gt;&lt;/p&gt; &lt;p&gt;dvdauthor -o dvd -x dvd.xml&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Check it worked with&lt;/p&gt; &lt;p&gt;mplayer dvd:// -dvd-device ./dvd&lt;/p&gt; &lt;p&gt;Burn the DVD with&lt;br /&gt;&lt;/p&gt;&lt;p&gt;growisofs -dvd-compat -Z /dev/dvdrw -dvd-video ./dvd/&lt;/p&gt;Example dvd.xml file used by dvdauthor above:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;dvdauthor&amp;gt;&lt;br /&gt;  &amp;lt;vmgm /&amp;gt;&lt;br /&gt;  &amp;lt;titleset&amp;gt;&lt;br /&gt;    &amp;lt;titles&amp;gt;&lt;br /&gt;      &amp;lt;video format="pal" aspect="16:9"/&amp;gt;&lt;br /&gt;      &amp;lt;audio format="ac3" lang="en"/&amp;gt;&lt;br /&gt;      &amp;lt;pgc&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00026.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00027.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00028.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00029.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00030.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00031.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00032.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00033.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00034.mpg"/&amp;gt;&lt;br /&gt;        &amp;lt;vob file="00035.mpg"/&amp;gt;&lt;br /&gt;      &amp;lt;/pgc&amp;gt;&lt;br /&gt;    &amp;lt;/titles&amp;gt;&lt;br /&gt;  &amp;lt;/titleset&amp;gt;&lt;br /&gt;&amp;lt;/dvdauthor&amp;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/6818189468244276547-8656454159385049406?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/8656454159385049406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=8656454159385049406' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8656454159385049406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8656454159385049406'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/09/howto-convert-and-write-avchd-mts-to.html' title='HOWTO: Convert and write AVCHD (.mts) to DVD with Linux'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-1211886208664804002</id><published>2009-09-04T01:47:00.000-07:00</published><updated>2009-09-04T06:09:19.857-07:00</updated><title type='text'>Convert video for nokia 5800 using ffmpeg in ubuntu</title><content type='html'>This gives outstanding results on nokia 5800:&lt;br /&gt;&lt;br /&gt;ffmpeg -i input.avi -vcodec mpeg4 -b 512k -s 640x360 -acodec libfaac -ab 128k -ac 2 -threads 4 output512k640x360.mp4&lt;br /&gt;&lt;br /&gt;The inputs can be in the many formats supported by ffmpeg.&lt;br /&gt;&lt;br /&gt;Apparently you can play H264 on the nokia 5800 which is supposed to be better quality but supposedly the max resolution is 360x240 or something. But the mpeg4 codec gives fabulous results too.&lt;br /&gt;&lt;br /&gt;See this link for some discussion on the subject &lt;a href="http://ubuntuforums.org/showthread.php?t=1125181"&gt;http://ubuntuforums.org/showthread.php?t=1125181&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-1211886208664804002?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/1211886208664804002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=1211886208664804002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/1211886208664804002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/1211886208664804002'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2009/09/convert-video-for-nokia-5800-using.html' title='Convert video for nokia 5800 using ffmpeg in ubuntu'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-8219188534939706631</id><published>2008-02-19T04:57:00.000-08:00</published><updated>2008-02-19T04:59:34.426-08:00</updated><title type='text'>Not using = equals in a Scala method definition</title><content type='html'>If the return type of a method is Unit,&lt;br /&gt;&lt;br /&gt;def add(b: Byte): Unit = sum += b&lt;br /&gt;&lt;br /&gt;then it can be written like this instead:&lt;br /&gt;&lt;br /&gt;def add(b: Byte) { sum += b }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-8219188534939706631?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/8219188534939706631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=8219188534939706631' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8219188534939706631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/8219188534939706631'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2008/02/not-using-equals-in-scala-method.html' title='Not using = equals in a Scala method definition'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-4151659573639504732</id><published>2008-02-19T04:37:00.000-08:00</published><updated>2008-02-19T04:47:21.437-08:00</updated><title type='text'>Scala nuggets not in  in the draft "Programming in Scala" book</title><content type='html'>I haven't seen these yet in the draft "Programming in Scala" book&lt;br /&gt;&lt;br /&gt;&lt;a href="http://neilbartlett.name/blog/2007/09/13/statically-checked-duck-typing-in-scala/"&gt;Statically Checked “Duck Typing” in Scala also known as structural types&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://scalada.blogspot.com/2008/02/thistype-for-chaining-method-calls.html"&gt;this.type for chaining method calls&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-4151659573639504732?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/4151659573639504732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=4151659573639504732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/4151659573639504732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/4151659573639504732'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2008/02/statically-checked-duck-typing-in-scala.html' title='Scala nuggets not in  in the draft &quot;Programming in Scala&quot; book'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-1129848025154400721</id><published>2008-02-18T16:28:00.000-08:00</published><updated>2009-10-09T14:03:04.658-07:00</updated><title type='text'>Translating Java to Scala</title><content type='html'>Java code to translate&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;&lt;br /&gt;   public byte[] getBytes(String path) throws IOException,&lt;br /&gt;   ClassNotFoundException {&lt;br /&gt;       System.out.println("reading: " + path);&lt;br /&gt;       File f = new File(classpath + (classpath.length()==0?"":File.separator)&lt;br /&gt;               + path.replace('.', File.separatorChar) + ".class");&lt;br /&gt;       int length = (int) (f.length());&lt;br /&gt;       if (length == 0) {&lt;br /&gt;           System.out.println("File length is zero");&lt;br /&gt;           throw new IOException("File length is zero: " + path);&lt;br /&gt;       } else {&lt;br /&gt;           byte[] bytecodes;&lt;br /&gt;           FileInputStream fin = null;&lt;br /&gt;           DataInputStream in = null;&lt;br /&gt;           try {&lt;br /&gt;               fin = new FileInputStream(f);&lt;br /&gt;               in = new DataInputStream(fin);&lt;br /&gt;&lt;br /&gt;               bytecodes = new byte[length];&lt;br /&gt;               in.readFully(bytecodes);&lt;br /&gt;           } finally {&lt;br /&gt;               try {&lt;br /&gt;                   in.close();&lt;br /&gt;               } catch (IOException e) {&lt;br /&gt;                   // We tried - keep going - the bytecodes may still be ok&lt;br /&gt;               }&lt;br /&gt;               try {&lt;br /&gt;                   fin.close();&lt;br /&gt;               } catch (IOException e) {&lt;br /&gt;                   // We tried - keep going - the bytecodes may still be ok&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;           return bytecodes;&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;First attempt&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;&lt;br /&gt; def getBytes(path: String) : Array[Byte] = {&lt;br /&gt;   println("reading: " + path);&lt;br /&gt;   val f = new File(classpath + (if (classpath.length()==0) "" else File.separator)  + path.replace('.', File.separatorChar) + ".class");&lt;br /&gt;   val length:Int = f.length().asInstanceOf[Int];&lt;br /&gt;   if (length == 0) {&lt;br /&gt;     println("File length is zero");&lt;br /&gt;     throw new IOException("File length is zero: " + path);&lt;br /&gt;   } else {&lt;br /&gt;     var fin: FileInputStream = null&lt;br /&gt;     var in: DataInputStream = null&lt;br /&gt;     var bytecodes:Array[Byte] = null&lt;br /&gt;     try {&lt;br /&gt;       fin = new FileInputStream(f);&lt;br /&gt;       in = new DataInputStream(fin);&lt;br /&gt;       bytecodes = new Array[Byte](length);&lt;br /&gt;       in.readFully(bytecodes);&lt;br /&gt;     } finally {&lt;br /&gt;       try { in.close(); } catch { case _ =&gt; }&lt;br /&gt;       try { fin.close(); } catch { case _ =&gt; }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     return bytecodes;&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Much nicer using resource management&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;&lt;br /&gt; def getBytes(path: String) : Array[Byte] = {&lt;br /&gt;   println("reading: " + path);&lt;br /&gt;   val f = new File(classpath + (if (classpath.length()==0) "" else File.separator)  + path.replace('.', File.separatorChar) + ".class");&lt;br /&gt;   val length:Int = f.length().asInstanceOf[Int];&lt;br /&gt;   if (length == 0) {&lt;br /&gt;     println("File length is zero");&lt;br /&gt;     throw new IOException("File length is zero: " + path);&lt;br /&gt;   } else {&lt;br /&gt;     val bytecodes = new Array[Byte](length);&lt;br /&gt;     withDataInputStream(f) { dis =&gt;&lt;br /&gt;       dis.readFully(bytecodes);&lt;br /&gt;     }&lt;br /&gt;     return bytecodes;&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; def withDataInputStream(f: File)(operation: DataInputStream =&gt; Unit) {&lt;br /&gt;   val fin = new FileInputStream(f)&lt;br /&gt;   val in = new DataInputStream(fin);&lt;br /&gt;   try {&lt;br /&gt;     operation(in)&lt;br /&gt;   } finally {&lt;br /&gt;     try { in.close(); } catch { case _ =&gt; }&lt;br /&gt;     try { fin.close(); } catch { case _ =&gt; }&lt;br /&gt;   }&lt;br /&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/6818189468244276547-1129848025154400721?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/1129848025154400721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=1129848025154400721' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/1129848025154400721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/1129848025154400721'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2008/02/coverting-java-to-scala.html' title='Translating Java to Scala'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6818189468244276547.post-2425274046549980053</id><published>2008-02-15T07:08:00.001-08:00</published><updated>2008-02-15T13:06:18.674-08:00</updated><title type='text'>Generic compute server in Scala using remote actors</title><content type='html'>So here's a very basic generic compute server in Scala. The idea is that a "server" accepts some task from a client, runs the task and then returns the result. The server is then ready again to accept another task from another client. The "work" can be anything and the server does not have to be compiled with the classes. It makes use of Scala actors running on the client and server. In this example there is one client and one server but there could be lots of servers, splitting up some parallelizable task. &lt;br /&gt;&lt;br /&gt;The tricky bit is getting the classes that represent the task to be run over to the server. As of Scala release 2.7.0-RC2, its now possible to specify the class loader for the remote actor and, in this example, the client sends a message to the server classloader to tell it where to get the classes from (if it hasn't got them already). The server uses a URLClassloader to fetch the classes via http from the client.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Prerequisites: &lt;br /&gt;You need at least Scala 2.7.0-RC2 &lt;br /&gt;You need Java 1.5 or above.&lt;br /&gt;&lt;br /&gt;There are three Scala files and two java files, all are listed in full in this blog post.&lt;br /&gt;&lt;br /&gt;Put the two scala files below on the server. Command.scala contains the commands that the client can send to the server. The "Execute" command takes a function to be executed on the server and could be anything at all. As a result the server will need to be able to dynamically fetch classes from the client in order to execute the function. The AddClassLoaderUrl command allows the client to tell the server where to get the classes from.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;/* Commands.scala */&lt;br /&gt;&lt;br /&gt;@serializable&lt;br /&gt;case class Message(body: Any) &lt;br /&gt;&lt;br /&gt;@serializable&lt;br /&gt;case class AddClassLoaderUrl(url: String) &lt;br /&gt;&lt;br /&gt;@serializable&lt;br /&gt;case class Execute(f: () =&gt; Any) &lt;br /&gt;&lt;br /&gt;@serializable&lt;br /&gt;case class Stop(body: String)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and &lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;/* Server.scala */&lt;br /&gt;&lt;br /&gt;import scala.actors.Actor&lt;br /&gt;import scala.actors.Actor._&lt;br /&gt;import scala.actors.remote.RemoteActor&lt;br /&gt;import scala.actors.remote.RemoteActor._&lt;br /&gt;import scala.actors.Debug&lt;br /&gt;import java.net.URLClassLoader&lt;br /&gt;import java.io._&lt;br /&gt;import java.net.MalformedURLException;&lt;br /&gt;import java.net.URL;&lt;br /&gt;import java.net.URLClassLoader;&lt;br /&gt;&lt;br /&gt;// Extend URLClassLoader so we can add a URL dynamically&lt;br /&gt;class MyURLClassLoader(urls:Array[URL], parent:ClassLoader) extends URLClassLoader(urls,parent) {&lt;br /&gt; &lt;br /&gt;  def add(urlString: String) {&lt;br /&gt;    // This is a protected method on URLClassLoader&lt;br /&gt;   addURL(new URL(urlString)) &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // override this method for debugging purposes, to see what classes are missing and where we are looking for them&lt;br /&gt;  override protected def findClass(name:String) : Class[Any]    = {&lt;br /&gt;    println("Classloader looking for class: " +name + " at URL: " + getURLs.mkString)&lt;br /&gt;    return super.findClass(name).asInstanceOf[Class[Any]] &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object Server extends Application {&lt;br /&gt;  &lt;br /&gt;    // See the low level communication messages between client and server&lt;br /&gt;    // Debug.level = 9&lt;br /&gt;&lt;br /&gt;    // Create a new URLClassLoader whose list of URLs we add to dynamically&lt;br /&gt;    val cl = new MyURLClassLoader(new Array[URL](0),getClass().getClassLoader())&lt;br /&gt;&lt;br /&gt;    // Tell the RemoteActor all about our classloader&lt;br /&gt;    // (If we don't as a minimum say RemoteActor.classLoader = getClass().getClassLoader() &lt;br /&gt;    // then no application classes are found). See issue https://lampsvn.epfl.ch/trac/scala/ticket/50&lt;br /&gt;    RemoteActor.classLoader = cl&lt;br /&gt;&lt;br /&gt;    actor {&lt;br /&gt;        alive(12345)&lt;br /&gt;        register('MYSERVICE, self)&lt;br /&gt;            // RemoteActor.classLoader is bound to TcpService and JavaSerializer here, &lt;br /&gt;            // and classloader cannot then be reassigned&lt;br /&gt;            // thats why we have to extend URLClassLoader to get access &lt;br /&gt;            // to protected addURL method&lt;br /&gt;&lt;br /&gt;        loop {&lt;br /&gt;            react {&lt;br /&gt;                case AddClassLoaderUrl(url) =&gt;&lt;br /&gt;                    cl.add(url)&lt;br /&gt;                    // synchronous reply&lt;br /&gt;                    reply("Thanks for the classloader url:" + url)&lt;br /&gt;                case Message(message) =&gt;&lt;br /&gt;                    // asynchronous reply&lt;br /&gt;                    sender ! Message("Thanks for the message: "  + message)&lt;br /&gt;                case Execute(f) =&gt;&lt;br /&gt;                    val result = f()&lt;br /&gt;                    // asynchronous reply&lt;br /&gt;                    sender ! result&lt;br /&gt;                case Stop(message) =&gt;&lt;br /&gt;                    exit()&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;then compile and run&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;fsc *.scala&lt;br /&gt;scala Server&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now for the client. Put Commands.scala (above) and Client.scala (below) in some directory on the client&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="scala"&gt;&lt;br /&gt;/* Client.scala */&lt;br /&gt;&lt;br /&gt;import scala.actors.Actor._&lt;br /&gt;import scala.actors.Debug&lt;br /&gt;import scala.actors.remote.Node&lt;br /&gt;import scala.actors.remote.TcpService._&lt;br /&gt;import scala.actors.remote.RemoteActor&lt;br /&gt;import scala.actors.remote.RemoteActor._&lt;br /&gt;import java.net.InetAddress&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@serializable&lt;br /&gt;class UnknownToServer {     &lt;br /&gt;    override def toString = { "I'm a class that the server does not know about, and so has to load dynamically"  } &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object Client extends Application {&lt;br /&gt;&lt;br /&gt;   // See the low level communication messages between client and server&lt;br /&gt;    // Debug.level = 9&lt;br /&gt;    &lt;br /&gt;    // If we don't as a minimum say RemoteActor.classLoader = getClass().getClassLoader() then nothing works &lt;br /&gt;    RemoteActor.classLoader =getClass().getClassLoader() &lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    actor {&lt;br /&gt;        val computeServer = select(Node("192.168.30.8", 12345), 'MYSERVICE)&lt;br /&gt;&lt;br /&gt;        // URL of the class file server, where the unkown class files can be server from&lt;br /&gt;        // InetAddress.getLocalHost().getHostAddress() should just be this machine's IP address&lt;br /&gt;        val classFileServerUrl = "http://" + InetAddress.getLocalHost().getHostAddress() + ":2001/"&lt;br /&gt;        &lt;br /&gt;        // Tell the computeServer how it can find any unknown classes. &lt;br /&gt;        // This message is sent syncronously (using !?), because the server needs the classloader setup &lt;br /&gt;        // before any further messages are *received* as messages are deserialized *before* being processed. &lt;br /&gt;        val reply = computeServer !? AddClassLoaderUrl(classFileServerUrl)&lt;br /&gt;        println(reply)&lt;br /&gt;        &lt;br /&gt;        // Send the server a message with a class it knows nothing about&lt;br /&gt;        computeServer ! Message(new UnknownToServer)&lt;br /&gt;        receive {&lt;br /&gt;            case Message(message) =&gt;&lt;br /&gt;                println(message)&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // This function is represented by an anonynous class which has to be loaded dynamically&lt;br /&gt;        def fn = () =&gt; (1 to 99).foldLeft(0) {println("Hello from a generic function passed dynamically to the server"); _+_}&lt;br /&gt;        &lt;br /&gt;        computeServer ! Execute(fn)&lt;br /&gt;        receive {&lt;br /&gt;            case x =&gt;&lt;br /&gt;                println("Result of generic compute function excuted on server:" + x)&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // computeServer ! Stop("foo")&lt;br /&gt;        exit &lt;br /&gt;    }&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;IMPORTANT: Change the 192.168.30.8 above to whatever the IP address of your server is (Find out with ipconfig on Window/ifconfig on Linux).&lt;br /&gt;&lt;br /&gt;Next we have two Java files that need to go in the same directory on the client. This is code from Sun that implements a very basic http server that serves up class files for that the server for any classes that it does not know about. This code could be translated into Scala, I just haven't got round to it yet.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;/*&lt;br /&gt; * ClassServer.java&lt;br /&gt; * &lt;br /&gt; * Copyright (c) 1996, 1996, 1997 Sun Microsystems, Inc. All Rights Reserved.&lt;br /&gt; * &lt;br /&gt; * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE&lt;br /&gt; * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;br /&gt; * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR&lt;br /&gt; * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES&lt;br /&gt; * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING&lt;br /&gt; * THIS SOFTWARE OR ITS DERIVATIVES.&lt;br /&gt; * &lt;br /&gt; * CopyrightVersion 1.1_beta&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;import java.io.BufferedReader;&lt;br /&gt;import java.io.DataInputStream;&lt;br /&gt;import java.io.DataOutputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.io.InputStreamReader;&lt;br /&gt;import java.net.ServerSocket;&lt;br /&gt;import java.net.Socket;&lt;br /&gt;import java.net.URL;&lt;br /&gt;import java.net.URLClassLoader;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * ClassServer is an abstract class that provides the basic functionality of a&lt;br /&gt; * mini-webserver, specialized to load class files only. A ClassServer must be&lt;br /&gt; * extended and the concrete subclass should define the &lt;b&gt;getBytes&lt;/b&gt; method&lt;br /&gt; * which is responsible for retrieving the bytecodes for a class.&lt;br /&gt; * &lt;p&gt;&lt;br /&gt; * &lt;br /&gt; * The ClassServer creates a thread that listens on a socket and accepts HTTP&lt;br /&gt; * GET requests. The HTTP response contains the bytecodes for the class that&lt;br /&gt; * requested in the GET header.&lt;br /&gt; * &lt;p&gt;&lt;br /&gt; * &lt;br /&gt; * For loading remote classes, an RMI application can use a concrete subclass of&lt;br /&gt; * this server in place of an HTTP server.&lt;br /&gt; * &lt;p&gt;&lt;br /&gt; * &lt;br /&gt; * @see ClassFileServer&lt;br /&gt; */&lt;br /&gt;public abstract class ClassServer implements Runnable {&lt;br /&gt;&lt;br /&gt; private ServerSocket server = null;&lt;br /&gt; private int port;&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Constructs a ClassServer that listens on &lt;b&gt;port&lt;/b&gt; and obtains a&lt;br /&gt;  * class's bytecodes using the method &lt;b&gt;getBytes&lt;/b&gt;.&lt;br /&gt;  * &lt;br /&gt;  * @param port&lt;br /&gt;  *            the port number&lt;br /&gt;  * @exception IOException&lt;br /&gt;  *                if the ClassServer could not listen on &lt;b&gt;port&lt;/b&gt;.&lt;br /&gt;  */&lt;br /&gt; protected ClassServer(int port) throws IOException {&lt;br /&gt;  this.port = port;&lt;br /&gt;  server = new ServerSocket(port);&lt;br /&gt;  newListener();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Returns an array of bytes containing the bytecodes for the class&lt;br /&gt;  * represented by the argument &lt;b&gt;path&lt;/b&gt;. The &lt;b&gt;path&lt;/b&gt; is a dot&lt;br /&gt;  * separated class name with the ".class" extension removed.&lt;br /&gt;  * &lt;br /&gt;  * @return the bytecodes for the class&lt;br /&gt;  * @exception ClassNotFoundException&lt;br /&gt;  *                if the class corresponding to &lt;b&gt;path&lt;/b&gt; could not be&lt;br /&gt;  *                loaded.&lt;br /&gt;  * @exception IOException&lt;br /&gt;  *                if error occurs reading the class&lt;br /&gt;  */&lt;br /&gt; public abstract byte[] getBytes(String path) throws IOException,&lt;br /&gt;   ClassNotFoundException;&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * The "listen" thread that accepts a connection to the server, parses the&lt;br /&gt;  * header to obtain the class file name and sends back the bytecodes for the&lt;br /&gt;  * class (or error if the class is not found or the response was malformed).&lt;br /&gt;  */&lt;br /&gt; public void run() {&lt;br /&gt;  Socket socket;&lt;br /&gt;&lt;br /&gt;  // accept a connection&lt;br /&gt;  try {&lt;br /&gt;   socket = server.accept();&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   System.out.println("Class Server died: " + e.getMessage());&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;   return;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // create a new thread to accept the next connection&lt;br /&gt;  newListener();&lt;br /&gt;&lt;br /&gt;  try {&lt;br /&gt;   DataOutputStream out = new DataOutputStream(socket&lt;br /&gt;     .getOutputStream());&lt;br /&gt;   try {&lt;br /&gt;    // get path to class file from header&lt;br /&gt;    DataInputStream in = new DataInputStream(socket&lt;br /&gt;      .getInputStream());&lt;br /&gt;    String path = getPath(in);&lt;br /&gt;    // retrieve bytecodes&lt;br /&gt;    byte[] bytecodes = getBytes(path);&lt;br /&gt;    // send bytecodes in response (assumes HTTP/1.0 or later)&lt;br /&gt;    try {&lt;br /&gt;     out.writeBytes("HTTP/1.0 200 OK\r\n");&lt;br /&gt;     out.writeBytes("Content-Length: " + bytecodes.length&lt;br /&gt;       + "\r\n");&lt;br /&gt;     out.writeBytes("Content-Type: application/java\r\n\r\n");&lt;br /&gt;     out.write(bytecodes);&lt;br /&gt;     out.flush();&lt;br /&gt;    } catch (IOException ie) {&lt;br /&gt;     return;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;   } catch (Exception e) {&lt;br /&gt;    // write out error response&lt;br /&gt;    out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");&lt;br /&gt;    out.writeBytes("Content-Type: text/html\r\n\r\n");&lt;br /&gt;    out.flush();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;  } catch (IOException ex) {&lt;br /&gt;   // eat exception (could log error to log file, but&lt;br /&gt;   // write out to stdout for now).&lt;br /&gt;   System.out.println("error writing response: " + ex.getMessage());&lt;br /&gt;   ex.printStackTrace();&lt;br /&gt;&lt;br /&gt;  } finally {&lt;br /&gt;   try {&lt;br /&gt;    socket.close();&lt;br /&gt;   } catch (IOException e) {&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Create a new thread to listen.&lt;br /&gt;  */&lt;br /&gt; private void newListener() {&lt;br /&gt;  (new Thread(this)).start();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Returns the path to the class file obtained from parsing the HTML header.&lt;br /&gt;  */&lt;br /&gt; private static String getPath(DataInputStream in) throws IOException {&lt;br /&gt;&lt;br /&gt;  BufferedReader d = new BufferedReader(new InputStreamReader(in));&lt;br /&gt;&lt;br /&gt;  String line = d.readLine();&lt;br /&gt;  String path = "";&lt;br /&gt;&lt;br /&gt;  System.out.println(line);&lt;br /&gt;&lt;br /&gt;  // extract class from GET line&lt;br /&gt;  if (line.startsWith("GET /")) {&lt;br /&gt;   line = line.substring(5, line.length() - 1).trim();&lt;br /&gt;&lt;br /&gt;   int index = line.indexOf(".class ");&lt;br /&gt;   if (index != -1) {&lt;br /&gt;    path = line.substring(0, index).replace('/', '.');&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // eat the rest of header&lt;br /&gt;  do {&lt;br /&gt;   line = d.readLine();&lt;br /&gt;   System.out.println(line);&lt;br /&gt;  } while ((line.length() != 0) &amp;&amp; (line.charAt(0) != '\r')&lt;br /&gt;    &amp;&amp; (line.charAt(0) != '\n'));&lt;br /&gt;&lt;br /&gt;  if (path.length() != 0) {&lt;br /&gt;   return path;&lt;br /&gt;  } else {&lt;br /&gt;   throw new IOException("Malformed Header");&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;/*&lt;br /&gt; * ClassFileServer.java&lt;br /&gt; * &lt;br /&gt; * Copyright (c) 1996, 1996, 1997 Sun Microsystems, Inc. All Rights Reserved.&lt;br /&gt; * &lt;br /&gt; * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE&lt;br /&gt; * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE&lt;br /&gt; * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR&lt;br /&gt; * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES&lt;br /&gt; * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING&lt;br /&gt; * THIS SOFTWARE OR ITS DERIVATIVES.&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;import java.io.DataInputStream;&lt;br /&gt;import java.io.File;&lt;br /&gt;import java.io.FileInputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * The ClassFileServer implements a ClassServer that reads class files from the&lt;br /&gt; * file system. See the doc for the "Main" method for how to run this server.&lt;br /&gt; */&lt;br /&gt;public class ClassFileServer extends ClassServer {&lt;br /&gt;&lt;br /&gt; private String classpath;&lt;br /&gt;&lt;br /&gt; private static int DefaultServerPort = 2001;&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Constructs a ClassFileServer.&lt;br /&gt;  * &lt;br /&gt;  * @param classpath&lt;br /&gt;  *            the classpath where the server locates classes&lt;br /&gt;  */&lt;br /&gt; public ClassFileServer(int port, String classpath) throws IOException {&lt;br /&gt;  super(port);&lt;br /&gt;  this.classpath = classpath;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Returns an array of bytes containing the bytecodes for the class&lt;br /&gt;  * represented by the argument &lt;b&gt;path&lt;/b&gt;. The &lt;b&gt;path&lt;/b&gt; is a dot&lt;br /&gt;  * separated class name with the ".class" extension removed.&lt;br /&gt;  * &lt;br /&gt;  * @return the bytecodes for the class&lt;br /&gt;  * @exception ClassNotFoundException&lt;br /&gt;  *                if the class corresponding to &lt;b&gt;path&lt;/b&gt; could not be&lt;br /&gt;  *                loaded.&lt;br /&gt;  */&lt;br /&gt; public byte[] getBytes(String path) throws IOException,&lt;br /&gt;   ClassNotFoundException {&lt;br /&gt;  System.out.println("reading: " + path);&lt;br /&gt;  String prefix = classpath.length() == 0 ? "" : classpath&lt;br /&gt;    + File.separator;&lt;br /&gt;  File f = new File(prefix + path.replace('.', File.separatorChar)&lt;br /&gt;    + ".class");&lt;br /&gt;  int length = (int) (f.length());&lt;br /&gt;  if (length == 0) {&lt;br /&gt;   Exception e = new IOException("File length is zero: " + path);&lt;br /&gt;   System.out.println(e);&lt;br /&gt;   throw new IOException("File length is zero: " + path);&lt;br /&gt;  } else {&lt;br /&gt;   FileInputStream fin = new FileInputStream(f);&lt;br /&gt;   DataInputStream in = new DataInputStream(fin);&lt;br /&gt;&lt;br /&gt;   byte[] bytecodes = new byte[length];&lt;br /&gt;   in.readFully(bytecodes);&lt;br /&gt;   return bytecodes;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Main method to create the class server that reads class files. This takes&lt;br /&gt;  * two command line arguments, the port on which the server accepts requests&lt;br /&gt;  * and the root of the classpath. To start up the server: &lt;br&gt;&lt;br /&gt;  * &lt;br&gt;&lt;br /&gt;  * &lt;br /&gt;  * &lt;code&gt;   java ClassFileServer &lt;port&gt; &lt;classpath&gt;&lt;br /&gt;  * &lt;/code&gt;&lt;br&gt;&lt;br /&gt;  * &lt;br&gt;&lt;br /&gt;  * &lt;br /&gt;  * The codebase of an RMI server using this webserver would simply contain a&lt;br /&gt;  * URL with the host and port of the web server (if the webserver's&lt;br /&gt;  * classpath is the same as the RMI server's classpath): &lt;br&gt;&lt;br /&gt;  * &lt;br&gt;&lt;br /&gt;  * &lt;br /&gt;  * &lt;code&gt;   java -Djava.rmi.server.codebase=http://zaphod:2001/ RMIServer&lt;br /&gt;  * &lt;/code&gt;&lt;br /&gt;  * &lt;br&gt;&lt;br /&gt;  * &lt;br&gt;&lt;br /&gt;  * &lt;br /&gt;  * You can create your own class server inside your RMI server application&lt;br /&gt;  * instead of running one separately. In your server main simply create a&lt;br /&gt;  * ClassFileServer: &lt;br&gt;&lt;br /&gt;  * &lt;br&gt;&lt;br /&gt;  * &lt;br /&gt;  * &lt;code&gt;   new ClassFileServer(port, classpath);&lt;br /&gt;  * &lt;/code&gt;&lt;br /&gt;  */&lt;br /&gt; public static void main(String args[]) {&lt;br /&gt;  int port = DefaultServerPort;&lt;br /&gt;  String classpath = "";&lt;br /&gt;&lt;br /&gt;  if (args.length &gt;= 1) {&lt;br /&gt;   port = Integer.parseInt(args[0]);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (args.length &gt;= 2) {&lt;br /&gt;   classpath = args[1];&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  try {&lt;br /&gt;   new ClassFileServer(port, classpath);&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   System.out&lt;br /&gt;     .println("Unable to start ClassServer: " + e.getMessage());&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and compile the scala and java with&lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;fsc *.scala&lt;br /&gt;javac *.java&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Run the java class server with &lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;java ClassFileServer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This will serve up the Scala classes that the server requests. This doesn't terminate so you'll have to open up another console/command window to run the Scala client. (Ideally this could be incorporated into the client.)&lt;br /&gt;&lt;br /&gt;Then run the client with&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;scala Client&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Which will run a simple function on the server and print the results.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6818189468244276547-2425274046549980053?l=quoiquilensoit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://quoiquilensoit.blogspot.com/feeds/2425274046549980053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6818189468244276547&amp;postID=2425274046549980053' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/2425274046549980053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6818189468244276547/posts/default/2425274046549980053'/><link rel='alternate' type='text/html' href='http://quoiquilensoit.blogspot.com/2008/02/generic-compute-server-in-scala-with.html' title='Generic compute server in Scala using remote actors'/><author><name>Tim Azzopardi</name><uri>http://www.blogger.com/profile/03169884264169945941</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_RMJbXtlMEI8/TJp5LiYTm_I/AAAAAAAACko/gq1Rj93I9v8/S220/timAtAppleCross.jpg'/></author><thr:total>2</thr:total></entry></feed>
