<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Code by Martin</title>
  <link href="http://martin.elwin.com/atom.xml" rel="self" />
  <link href="http://martin.elwin.com" />
  <updated>2010-06-04T14:54:22+02:00</updated>
  <id>http://martin.elwin.com</id>
  <author>
    <name>Martin Elwin</name>
    <email>martin@elwin.com</email>
  </author>
  <entry>
    <title>Binary Search</title>
    <link href="http://martin.elwin.com/blog/2010/04/binary-search/" />
    <updated>2010-04-21T20:41:00+02:00</updated>
    <id>http://martin.elwin.com/blog/2010/04/binary-search</id>
    <content type="html">
      &lt;p&gt;&lt;a href=&quot;http://reprog.wordpress.com/2010/04/21/binary-search-redux-part-1/&quot;/&gt;Mike Taylor&lt;/a&gt; noted in a blog post that in the book Programming Pearls it is mentioned that no more than 10% of developers can correctly implement a binary search. Appalling!&lt;/p&gt;
      
      &lt;p&gt;Let&#8217;s see if I am in that 10% or not&#8230;&lt;/p&gt;
      
      &lt;p&gt;As I&#8217;ve found myself using Ruby more and more lately, I thought I&#8217;d try to implement the binary search using that language.&lt;/p&gt;
      
      &lt;p&gt;Here&#8217;s my stab:&lt;/p&gt;
      
      &lt;script src=&quot;http://gist.github.com/374222.js&quot;&gt;&lt;/script&gt;
      
      
      &lt;p&gt;The script includes code to run the binary search through the test cases for the exercise created by &lt;a href=&quot;http://www.tiac.net/~sw&quot;&gt;Steve Witham&lt;/a&gt;. And once the file reading worked - all tests actually passed (or the code incorrectly shows them as passed&#8230; ;).&lt;/p&gt;
      
      &lt;p&gt;Good training this!&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Migrated To Octopress</title>
    <link href="http://martin.elwin.com/blog/2010/03/migrated-to-octopress/" />
    <updated>2010-03-19T21:23:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2010/03/migrated-to-octopress</id>
    <content type="html">
      &lt;p&gt;Like &lt;a href=&quot;http://jonasboner.com/2009/01/07/blogging-like-a-hacker-using-git-and-jekyll.html&quot;&gt;all&lt;/a&gt; &lt;a href=&quot;http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html&quot;&gt;cool&lt;/a&gt; &lt;a href=&quot;http://wiki.github.com/mojombo/jekyll/sites&quot;&gt;kids&lt;/a&gt; blogging nowadays, as part of the attempt to rejuvinate the blog, I&#8217;ve switched to &lt;a href=&quot;http://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt;. Or, rather, the extended fork &lt;a href=&quot;http://github.com/imathis/octopress&quot;&gt;Octopress&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;As part of the migration I wanted to extract all the old posts from Wordpress into the proper markdown format used by Jekyll.&lt;/p&gt;
      
      &lt;p&gt;Jekyll includes a migration script for Wordpress, but this used a direct database connection to the Wordpress MySQL server to extract a minimum amount of information for each blog post. To avoid missing information that I later might want after having shut down the Wordpress server, I wanted to base the migration on a full XML export from Wordpress. This way I could go back and extract more information from the old posts, if, and when, needed.&lt;/p&gt;
      
      &lt;p&gt;Seeing this as a chance to play with Ruby - a language I&#8217;ve only dabbled in previously - I set out to build a simple Wordpress XML-&gt;Jekyll converter. The converter reads the Wordpress export and converts all blog posts into separate files with a proper Yaml frontmatter. It also converts the syntax highlighting markup, code markup and headings into the corresponding markdown conventions. The rest of the HTML is left alone.&lt;/p&gt;
      
      &lt;p&gt;For the images I just copied the files in the old Wordpress structure into the new blog directory layout so that the URLs still match. Not the nicest way, but I was too lazy to do anything about it just yet.&lt;/p&gt;
      
      &lt;p&gt;Anywho - the source for the Wordpress XML converter is available in the &lt;a href=&quot;http://github.com/melwin/octopress/blob/blog/source/_import/wordpress_xml_import.rb&quot;&gt;blog branch of my fork of Octopress&lt;/a&gt;. The source is also given below. To use, just run with the filename of the Wordpress XML export as the first argument.&lt;/p&gt;
      
      &lt;p&gt;It&#8217;s my first publicly available Ruby program - so be careful. Improvements welcome!&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
      
      &lt;script src=&quot;http://gist.github.com/374148.js&quot;&gt;&lt;/script&gt;
    </content>
  </entry>
  <entry>
    <title>Nginx</title>
    <link href="http://martin.elwin.com/blog/2010/03/nginx/" />
    <updated>2010-03-16T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2010/03/nginx</id>
    <content type="html">
      &lt;p&gt;For that fresh new feeling I switched this site from Apache2 to &lt;a href=&quot;http://nginx.org&quot;&gt;Nginx&lt;/a&gt;. A quick compile of the source package and following the &lt;a href=&quot;http://wiki.nginx.org/Wordpress&quot;&gt;instructions&lt;/a&gt; on hooking it up with Wordpress over fastcgi using php-cgi and we&#8217;re done!&lt;/p&gt;
      
      &lt;p&gt;Feels good with a server handling the &lt;a href=&quot;http://en.wikipedia.org/wiki/C10k_problem&quot;&gt;C10K&lt;/a&gt; problem - and it has a fairly decent configuration language IMHO.&lt;/p&gt;
      
      &lt;p&gt;Also looking forward to use Nginx more in the days to come as a the web frontend for development tools server at work hosting, among some things:&lt;/p&gt;
      
      &lt;ul&gt;
          &lt;li&gt;Gitorious&lt;/li&gt;
          &lt;li&gt;Redmine&lt;/li&gt;
          &lt;li&gt;Hudson&lt;/li&gt;
          &lt;li&gt;Nexus&lt;/li&gt;
      &lt;/ul&gt;
      
      
      &lt;p&gt;Will post more about this later!&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>New Direction?</title>
    <link href="http://martin.elwin.com/blog/2010/03/new-direction/" />
    <updated>2010-03-16T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2010/03/new-direction</id>
    <content type="html">
      &lt;p&gt;More than a full year since last post - this might not be working as well as I had hoped&#8230;!&lt;/p&gt;
      
      &lt;p&gt;Finding the time and inspiration to write between the day job and private commitments turns out to be a challenge. Instead of seeing this as a failure, however, I will try to learn from the experience and attempt to find a new way of relating to the blog. Perhaps by being less long winded (!) in each post I could get a few more out there. There are still a lot of things going on I would like to capture, but the previous form is clearly not working.&lt;/p&gt;
      
      &lt;p&gt;So - let&#8217;s try to shake things up and see how that works!&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>The Hitchhiker&#8217;s Guide to an Ioke Dev Env From Source (part 5: Ioke and the REPL)</title>
    <link href="http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-5/" />
    <updated>2009-01-23T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-5</id>
    <content type="html">
      &lt;p&gt;This is the fifth part in a series of posts for non-experts about setting up an Ioke development environment on Linux. Please see the previous posts to start at the beginning:&lt;/p&gt;
      
      &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-1/&quot;&gt;Part 1: Git&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-2/&quot;&gt;Part 2: Emacs&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-3/&quot;&gt;Part 3: emacs-starter-kit&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-4/&quot;&gt;Part 4: Java and Ant&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      
      &lt;p&gt;This time we will finally get the Ioke source code, build it, and test the Ioke &lt;a href=&quot;http://en.wikipedia.org/wiki/REPL&quot;&gt;REPL&lt;/a&gt;!&lt;/p&gt;
      
      &lt;h3&gt;Ioke&lt;/h3&gt;
      
      &lt;p&gt;Ioke uses &lt;a href=&quot;http://git-scm.com&quot;&gt;Git&lt;/a&gt; as the source code versioning tool, with a &lt;a href=&quot;http://github.com/olabini/ioke&quot;&gt;public repository&lt;/a&gt; set up on &lt;a href=&quot;http://github.com/&quot;&gt;GitHub&lt;/a&gt; (soon I&#8217;ll be linking like Jeff Atwood).&lt;/p&gt;
      
      &lt;p&gt;So - let&#8217;s get Ioke using Git by cloning Ola&#8217;s repository:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/work
      ~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone git://github.com/olabini/ioke
      Initialized empty Git repository in /home/melwin/work/ioke/.git/
      remote: Counting objects: 9221, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      remote: Compressing objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2941/2941&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      remote: Total 9221 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 5782&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, reused 8656 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 5351&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      Receiving objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;9221/9221&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 45.95 MiB | 399 KiB/s, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      Resolving deltas: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;5782/5782&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Great - let&#8217;s quickly move on to the build step:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;ioke
      ~/work/ioke&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ant
      ...
           &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;java&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; 2606 examples, 0 failures
      jar:
            &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;jar&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; Building jar: /home/melwin/work/ioke/lib/ioke.jar
      
      BUILD SUCCESSFUL
      Total &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt;: 22 seconds
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Running just &lt;code&gt;ant&lt;/code&gt; will execute the default target in the &lt;code&gt;build.xml&lt;/code&gt; file. This target will make sure Ioke is compiled and the test suite is run.&lt;/p&gt;
      
      &lt;p&gt;At the end is a summary of the test results - if these are not all successful you might have a problem with the environment or you might have checked out a broken build from the repository.&lt;/p&gt;
      
      &lt;h3&gt;The Ioke REPL&lt;/h3&gt;
      
      &lt;p&gt;Now all is installed and Ioke is compiled, so let&#8217;s fire up the REPL. This is done by just running the main Ioke binary:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work/ioke/&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;bin/ioke
      iik&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;When doing this we get the &lt;code&gt;iik&gt;&lt;/code&gt; REPL prompt. From here we can execute most Ioke code. Let&#8217;s try to print a string:&lt;/p&gt;
      
      &lt;p&gt;Here we create a Text (Ioke&#8217;s string type) literal and send it the message &lt;code&gt;println&lt;/code&gt;, which will cause the text to be printed to the console. The return type of &lt;code&gt;println&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt; (similar to null), which is printed by the REPL itself. After that we get the prompt back and can execute another line.&lt;/p&gt;
      
      &lt;p&gt;Let&#8217;s try a little more complex example - the factorial:&lt;/p&gt;
      
      &lt;p&gt;Note how the REPL prints the method definition in a canonical form - it makes it obvious how Ioke parses the code, what are messages and what are arguments.&lt;/p&gt;
      
      &lt;p&gt;Let&#8217;s run our new factorial function:&lt;/p&gt;
      
      &lt;p&gt;Ioke handles arbitrarily big numbers, so we don&#8217;t need to think about what fits in a certain number of bits.&lt;/p&gt;
      
      &lt;p&gt;The Iik REPL also comes with a simple debugger, which helps with handling conditions. For instance, let&#8217;s try to run the fact method, passing a message which doesn&#8217;t mean anything (yet):&lt;/p&gt;
      
      &lt;p&gt;The above output shows that when we try to reference something that doesn&#8217;t exist we get a chance to provide that value. Here I decided to provide a value using the useValue restart and entered the value 5. This let the method continue executing and the result was printed.&lt;/p&gt;
      
      &lt;p&gt;To exit the REPL, just type: &lt;code&gt;exit&lt;/code&gt;&lt;/p&gt;
      
      &lt;p&gt;Next up are the Emacs modes for Ioke - stay tuned!&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>The Hitchhiker&#8217;s Guide to an Ioke Dev Env From Source (part 4: Java+Ant)</title>
    <link href="http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-4/" />
    <updated>2009-01-22T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-4</id>
    <content type="html">
      &lt;p&gt;This is the fourth part in a series of posts for non-experts about setting up an Ioke development environment on Linux. Please see the previous posts to start at the beginning:&lt;/p&gt;
      
      &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-1/&quot;&gt;Part 1: Git&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-2/&quot;&gt;Part 2: Emacs&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-3/&quot;&gt;Part 3: emacs-starter-kit&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      
      &lt;p&gt;It took a bit longer than anticipated to get to this point, as I got side tracked with the &lt;a href=&quot;http://martin.elwin.com/blog/2009/01/type-checking-in-ioke-java-methods/&quot;&gt;Ioke type checking activities&lt;/a&gt;. But now when &lt;a href=&quot;http://ioke.org&quot;&gt;Ioke S&lt;/a&gt; is out we can continue with the series. So! We&#8217;re getting closer&#8230; Only a few more things to go.&lt;/p&gt;
      
      &lt;h3&gt;Installing Java&lt;/h3&gt;
      
      &lt;p&gt;As the current version of Ioke is implemented to run on a Java Virtual Machine, we need to get hold of one of those to be able to continue. The JVM brand we will install here is the latest stable one  produced by Sun.&lt;/p&gt;
      
      &lt;p&gt;What we need is Java SE Development Kit 6u11 for Linux, Multi-language, and the the filename for this is &lt;code&gt;jdk-6u11-linux-i586.bin&lt;/code&gt;. Note that this is &lt;em&gt;not&lt;/em&gt; the &lt;code&gt;.rpm.bin&lt;/code&gt;, which is also available.&lt;/p&gt;
      
      &lt;p&gt;Download the file from &lt;a href=&quot;http://java.sun.com/javase/downloads/index.jsp&quot;&gt;http://java.sun.com/javase/downloads/index.jsp&lt;/a&gt; (I&#8217;m sure you can find it) and put it in the &lt;code&gt;~/work&lt;/code&gt; directory.&lt;/p&gt;
      
      &lt;p&gt;To unpack the file, let&#8217;s make it executable and then run it:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/work
      ~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/work                   
      ~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;chmod a+x jdk-6u11-linux-i586.bin 
      ~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./jdk-6u11-linux-i586.bin         
      ... lots of legalese here...
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Once the license agreement is accepted, the JVM will unpack itself into the directory &lt;code&gt;~/work/jdk1.6.0_11&lt;/code&gt;. Let&#8217;s move it to where we want it and add &lt;code&gt;java&lt;/code&gt; and &lt;code&gt;javac&lt;/code&gt; to the &lt;code&gt;~/bin&lt;/code&gt; directory as before:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;mv jdk1.6.0_11 ../opt
      ~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/bin
      ~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ln -s ../opt/jdk1.6.0_11/bin/java
      ~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ln -s ../opt/jdk1.6.0_11/bin/javac
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;And test it:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;java -version
      java version &lt;span class=&quot;s2&quot;&gt;&quot;1.6.0_11&quot;&lt;/span&gt;
      Java&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;TM&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; SE Runtime Environment &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;build 1.6.0_11-b03&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      Java HotSpot&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;TM&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; Client VM &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;build 11.0-b16, mixed mode, sharing&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;That done - let&#8217;s move on to Ant.&lt;/p&gt;
      
      &lt;h3&gt;Ant&lt;/h3&gt;
      
      &lt;p&gt;Ioke uses &lt;a href=&quot;http://ant.apache.org&quot;&gt;Apache Ant&lt;/a&gt; to handle the build process, so to build Ioke we need to get Ant installed.&lt;/p&gt;
      
      &lt;p&gt;Let&#8217;s download the Ant distributable package and unpack it in one go - as we did with Git:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/opt
      ~/opt&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wget -O - http://www.apache.org/dist/ant/binaries/apache-ant-1.7.1-bin.tar.bz2 | tar xjv
      &lt;/lang&gt;
      
      And add it to the ~/bin directory again so it&lt;span class=&quot;err&quot;&gt;&#39;&lt;/span&gt;s on the path:
      
      &lt;pre &lt;span class=&quot;nv&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;sh&quot;&lt;/span&gt;&gt;
      ~/opt&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/bin
      ~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ln -s ../opt/apache-ant-1.7.1/bin/ant
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Let&#8217;s try it out:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ant -version
      Apache Ant version 1.7.1 compiled on June 27 2008
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Looking good!&lt;/p&gt;
      
      &lt;p&gt;Soon to come: How to get the Ioke source and build it.&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-5/&quot;&gt;Part 5: Ioke and the REPL&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Type Checking in Ioke Java Methods</title>
    <link href="http://martin.elwin.com/blog/2009/01/type-checking-in-ioke-java-methods/" />
    <updated>2009-01-19T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2009/01/type-checking-in-ioke-java-methods</id>
    <content type="html">
      &lt;p&gt;Ola Bini recently issued &lt;a href=&quot;http://kenai.com/projects/ioke/lists/dev/archive/2009-01/message/21&quot;&gt;a call to arms&lt;/a&gt; to help with the receiver and argument validation for Java methods in Ioke. These are the Ioke methods that are implemented in Java, instead of in Ioke itself.&lt;/p&gt;
      
      &lt;p&gt;The Java methods usually operate on the specific data contained within Ioke objects. This data corresponds to different Java classes, depending on what the Ioke object should hold. For instance, an Ioke List contains inside the data area a Java List. To operate on this List the Java code needs to get hold of the List reference - and it does this in a lot of cases by assuming the data object is of a certain type and casts to this type. If the data object is of a different type then a Java &lt;code&gt;ClassCastException&lt;/code&gt; is thrown, which makes the interpreter quit.&lt;/p&gt;
      
      &lt;p&gt;Since Ola mailed the call to arms a number of things have happened. A few people (including myself) have volunteered to help out with adding the validation code. Additionally, a few supporting methods and additions have been added to the Ioke code base to simplify adding type checks to the existing code. And it&#8217;s these additions that I will talk about here.&lt;/p&gt;
      
      &lt;h3&gt;Current Code&lt;/h3&gt;
      
      &lt;p&gt;As an example what the new type validations can look like I will use the &lt;code&gt;List +&lt;/code&gt; method that Ola also mentioned in the example.&lt;/p&gt;
      
      &lt;p&gt;This is the previous code from &lt;a href=&quot;http://github.com/olabini/ioke/blob/e3018142943253f0fd13a967ffb68d39087d9600/src/main/ioke/lang/IokeList.java&quot;&gt;IokeList.java&lt;/a&gt;:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;registerMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newJavaMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;returns a new list that contains the receivers elements and the elements of the list sent in as the argument.&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JavaMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;+&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultArgumentsDefinition&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ARGUMENTS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultArgumentsDefinition&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withRequiredPositional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;otherList&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getArguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
              
              &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
              &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DefaultArgumentsDefinition&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getArguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ARGUMENTS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
              
              &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
              &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;activate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ControlFlow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;();&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;getArguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getEvaluatedArguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;());&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;();&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;newList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;newList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}));&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;h3&gt;New Type Checks&lt;/h3&gt;
      
      &lt;p&gt;The key to the new validation are two new classes, which extend the functionality of the normal &lt;code&gt;JavaMethod&lt;/code&gt; class with type checking functionality. These are:&lt;/p&gt;
      
      &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;http://github.com/olabini/ioke/blob/0e20b492b8e057e9d2c006698deca02ebf8f45f7/src/main/ioke/lang/TypeCheckingArgumentsDefinition.java&quot;&gt;TypeCheckingArgumentsDefinition&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://github.com/olabini/ioke/blob/0e20b492b8e057e9d2c006698deca02ebf8f45f7/src/main/ioke/lang/TypeCheckingJavaMethod.java&quot;&gt;TypeCheckingJavaMethod&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      
      &lt;p&gt;When using these to define the Java method we can &#8220;annotate&#8221; the arguments definition with types for both the arguments and the receiver. By then implementing the appropriate &lt;code&gt;activate(...)&lt;/code&gt; the super class takes care of evaluating and validating (converting as appropriate) the receiver and arguments.&lt;/p&gt;
      
      &lt;p&gt;For instance, for the &lt;code&gt;List +&lt;/code&gt; example, the above code gets changed to the following:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;registerMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newJavaMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;returns a new list that contains the receivers elements and the elements of the list sent in as the argument.&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TypeCheckingJavaMethod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;+&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TypeCheckingArgumentsDefinition&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ARGUMENTS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TypeCheckingArgumentsDefinition&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;receiverMustMimic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withRequiredPositional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;otherList&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;whichMustMimic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getArguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
              
              &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
              &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TypeCheckingArgumentsDefinition&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getArguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ARGUMENTS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
              
              &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
              &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;activate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keywords&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ControlFlow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&gt;();&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;newList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;newList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IokeObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}));&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Note that most of the boiler plate code for arguments handling (which most JavaMethods do) is removed, leaving a clean implementation of the necessary logic - to concatenate two lists in this case.&lt;/p&gt;
      
      &lt;p&gt;A few things are done:&lt;/p&gt;
      
      &lt;ol&gt;
          &lt;li&gt;The JavaMethod is changed to TypeCheckingJavaMethod&lt;/li&gt;
          &lt;li&gt;The arguments definition is changed to a TypeCheckingArgumentsDefinition&lt;/li&gt;
          &lt;li&gt;The appropriate types are added to the arguments definition&lt;/li&gt;
          &lt;li&gt;Return type of getArguments is changed to TypeCheckingArgumentsDefinition&lt;/li&gt;
          &lt;li&gt;The active method is changed to the one which gets the arguments list and keywords&lt;/li&gt;
          &lt;li&gt;The manual call to getArguments().getEvaluatedArguments() is removed as we now get the arguments passed&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;p&gt;The relevant tests for this, which should be added to the &lt;code&gt;list_spec.ik&lt;/code&gt; test file, could look like:&lt;/p&gt;
      
      &lt;p&gt;So for you to do:&lt;/p&gt;
      
      &lt;ol&gt;
          &lt;li&gt;Fork Ioke&lt;/li&gt;
          &lt;li&gt;Pick a `IokeData` subclass which no one has started on yet (check with Ola/naeu/me in the IRC channel #ioke on FreeNode)&lt;/li&gt;
              &lt;li&gt;Identify a method which makes faulty assumptions on receiver or arguments&lt;/li&gt;
          &lt;li&gt;Add a test as per the above to validate the arguments and receiver&lt;/li&gt;
          &lt;li&gt;Change `JavaMethod` implementation as per the above to fix the test&lt;/li&gt;
          &lt;li&gt;Commit test and fix in togther to your fork&lt;/li&gt;
          &lt;li&gt;Rinse and repeat until the whole file is done&lt;/li&gt;
          &lt;li&gt;Convince Ola to pull your fork&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;p&gt;Let&#8217;s get crackin&#8217;!&lt;/p&gt;
      
      &lt;p&gt;(but first - back to normal work&#8230; :)&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>The Hitchhiker&#8217;s Guide to an Ioke Dev Env From Source (part 2: Emacs)</title>
    <link href="http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-2/" />
    <updated>2009-01-13T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-2</id>
    <content type="html">
      &lt;p&gt;This is the second part in a series of posts for non-experts about setting up an Ioke development environment on Linux. Please see the previous post to start at the beginning:&lt;/p&gt;
      
      &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-1/&quot;&gt;Part 1: Git&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      
      &lt;p&gt;In this post we will install GNU Emacs from source and also get a basic configuration set up using the &lt;a href=&quot;http://github.com/technomancy/emacs-starter-kit/tree/master&quot;&gt;emacs-starter-kit&lt;/a&gt;.&lt;/p&gt;
      
      &lt;p&gt;If you already have Emacs installed and have an old configuration laying around you probably want to make a backup of this before following the below instructions. This post assumes that there is no Emacs installed and that the user doesn&#8217;t have any Emacs configuration in the home directory.&lt;/p&gt;
      
      &lt;h3&gt;Installing Emacs&lt;/h3&gt;
      
      &lt;p&gt;Git is an efficient Distributed Version Control System. Although the primary VCS for Emacs is still CVS - and it looks like they are moving towards Bazaar - we&#8217;ll get the Emacs sources from the &lt;a href=&quot;Emacs Git mirror&quot;&gt;Emacs Git mirror&lt;/a&gt;. We want to be &lt;a href=&quot;http://www.unethicalblogger.com/posts/2009/01/im_using_git_because_it_makes_me_feel_cool&quot;&gt;cool&lt;/a&gt;, right?&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;work
      ~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone --depth 1 git://git.sv.gnu.org/emacs.git
      Initialized empty Git repository in /home/melwin/work/emacs/.git/
      remote: Counting objects: 46400, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      remote: Compressing objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;24410/24410&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      remote: Total 46400 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 41204&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, reused 25501 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;delta 21836&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      Receiving objects: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;46400/46400&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 74.38 MiB | 213 KiB/s, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      Resolving deltas: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;41204/41204&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      Checking out files: 100% &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2837/2837&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;.
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;With the &lt;code&gt;--depth 1&lt;/code&gt; parameter we limit the history so that we only get the latest version of the files - in this case we&#8217;re not interested in the full history.&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As we&#8217;re getting the bleeding edge source code of Emacs, it could happen that the build is broken. I&#8217;ve never had this happen on me, but in case you get strange errors when building Emacs, this might be the reason. Usually such problems are fixed quickly, so try to do a &lt;code&gt;git pull&lt;/code&gt; a bit later to update the downloaded source.&lt;/p&gt;
      
      &lt;p&gt;Previously, to get fun things like &lt;a href=&quot;http://www.emacswiki.org/emacs/MultiTTYSupport&quot;&gt;multi-tty support&lt;/a&gt; and &lt;a href=&quot;http://www.emacswiki.org/emacs/XftGnuEmacs&quot;&gt;smooth fonts&lt;/a&gt;, we had to get specific feature branches of Emacs. Nowadays, however, all the things we want are merged into the Emacs master branch. Before building, the only thing we need to do is to make sure the necessary development libraries are installed. In case you wonder how I came up with this list: the good ol&#8217; method of trial and error. I simply ran the &lt;code&gt;configure&lt;/code&gt; command and checked the error messages. This helped me identify the needed libraries. Now you can reap the benefits by just doing the following:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo apt-get install libgtk2.0-dev libxpm-dev libjpeg-dev libgif-dev libtiff-dev
      ...
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;&#8230; and then run the classical &lt;code&gt;configure&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt; and &lt;code&gt;make install&lt;/code&gt;:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;emacs
      ~/work/emacs&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./configure --prefix&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/opt/emacs-23.0.60
      ...
      ~/work/emacs&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make
      ...
      ~/work/emacs&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make install
      ...
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Phew. That burned som CPU cycles&#8230;! Once done - let&#8217;s add it to our &lt;code&gt;bin&lt;/code&gt; directory, just as we did with Git.&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work/emacs&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/bin
      ~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ln -s ../opt/emacs-23.0.60/bin/emacs
      ~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ln -s ../opt/emacs-23.0.60/bin/emacsclient
      ~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ls
      emacs  emacsclient  git
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Time to test. Just run emacs:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/bin% emacs
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;This should show you an Emacs window with a pretty(?) GNU.&lt;/p&gt;
      
      &lt;p&gt;&lt;img src=&quot;http://martin.elwin.com/blog/wp-content/uploads/2009/01/emacs-window.png&quot; alt=&quot;Emacs Window&quot; title=&quot;Emacs Window&quot; width=&quot;694&quot; height=&quot;671&quot; class=&quot;alignnone size-full wp-image-89&quot; /&gt;&lt;/p&gt;
      
      &lt;p&gt;If you&#8217;re completely new to Emacs, this might be a good opportunity to run the Emacs tutorial. Emacs is a self-documenting editor, which means that most things that you might want to learn about Emacs can be found inside the editor itself - including information about internal functions and libraries.&lt;/p&gt;
      
      &lt;p&gt;To run the tutorial, just press &lt;code&gt;Ctrl+h t&lt;/code&gt; (that is, &lt;code&gt;control&lt;/code&gt; and &lt;code&gt;h&lt;/code&gt;, release control, then press &lt;code&gt;t&lt;/code&gt;), or, in Emacs lingo, &lt;code&gt;C-h t&lt;/code&gt; (which is the convention I&#8217;ll use from now on).&lt;/p&gt;
      
      &lt;p&gt;Once you&#8217;ve learned enough (you did complete the whole thing, right?), just quit using &lt;code&gt;C-x c&lt;/code&gt;.&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To update the source code and rebuild, do a &lt;code&gt;git pull&lt;/code&gt; in the &lt;code&gt;emacs&lt;/code&gt; directory, then &lt;code&gt;make distclean&lt;/code&gt; (in case some build files changed) and then perform the compile and installation as per the above again.&lt;/p&gt;
      
      &lt;p&gt;Next up is &lt;code&gt;emacs-starter-kit&lt;/code&gt; to get more functionality in Emacs and a decent default configuration to help us get going - stay tuned!&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-3/&quot;&gt;Part 3: emacs-starter-kit&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>The Hitchhiker&#8217;s Guide to an Ioke Dev Env From Source (part 3: emacs-starter-kit)</title>
    <link href="http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-3/" />
    <updated>2009-01-13T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-3</id>
    <content type="html">
      &lt;p&gt;This is the third part in a series of posts for non-experts about setting up an Ioke development environment on Linux. Please see the previous posts to start at the beginning:&lt;/p&gt;
      
      &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-1/&quot;&gt;Part 1: Git&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-2/&quot;&gt;Part 2: Emacs&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      
      &lt;p&gt;The &lt;a href=&quot;http://github.com/technomancy/emacs-starter-kit/tree/master&quot;&gt;emacs-starter-kit&lt;/a&gt; is a set of base configuration for Emacs. It contains a number of useful elisp libraries, with a slight focus on dynamic languages.&lt;/p&gt;
      
      &lt;p&gt;To install it, perform the following steps (note that we move any existing Emacs configuration out of the way first to avoid stomping what you currently have):&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work/emacs&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;
      ~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;mv .emacs.d .emacs.d.old
      ~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;mv .emacsrc .emacsrc.old
      ~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone git://github.com/technomancy/emacs-starter-kit.git .emacs.d
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;If you now start Emacs again you&#8217;ll see that the menu bar and the toolbar is gone. This is the default in emacs-starter-kit as most Emacs users don&#8217;t find them useful. For new users the menu bar can sometimes come in handy, to get it back temporarily, just press &lt;code&gt;F1&lt;/code&gt;.&lt;/p&gt;
      
      &lt;h3&gt;Configuring Emacs&lt;/h3&gt;
      
      &lt;p&gt;If you want to add your own customizations to Emacs when using emacs-starter-kit, just add an Emacs LISP file called &lt;em&gt;&lt;code&gt;username.el&lt;/code&gt;&lt;/em&gt;, or &lt;em&gt;&lt;code&gt;hostname.el&lt;/code&gt;&lt;/em&gt;, in the &lt;code&gt;~/.emacs.d&lt;/code&gt; directory. For instance, to make the menu bar always visible:&lt;/p&gt;
      
      &lt;ol&gt;
      &lt;li&gt;Open Emacs, if it&#8217;s not open already.&lt;/li&gt;
      &lt;li&gt;Press &lt;code&gt;C-x C-f&lt;/code&gt; and type in: &lt;code&gt;~/.emacs.d/username.el&lt;/code&gt;&lt;br&gt;Where &lt;em&gt;username&lt;/em&gt; is the name you log in with (for instance, in my case the complete filename is &lt;code&gt;melwin.el&lt;/code&gt;).&lt;/li&gt;
      &lt;li&gt;Type in the following in the file:
      
      &lt;pre&gt;&lt;code&gt; (menu-bar-mode 1)
      &lt;/code&gt;&lt;/pre&gt;
      
      &lt;p&gt;And save the file with &lt;code&gt;C-x s&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
      &lt;li&gt;Now quit (&lt;code&gt;C-x c&lt;/code&gt;) and restart and you&#8217;ll see that the menu bar is shown.&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;h3&gt;Working with Magit&lt;/h3&gt;
      
      &lt;p&gt;emacs-starter-kit includes, among many other things, the very nice &lt;a href=&quot;http://zagadka.vm.bytemark.co.uk/magit/magit.html&quot;&gt;Magit Git mode for Emacs&lt;/a&gt;, which gives you a nice interface for working with a Git repository.&lt;/p&gt;
      
      &lt;p&gt;Let&#8217;s use this mode to commit our recent changes to the configuration file to our local clone of the &lt;code&gt;emacs-starter-kit&lt;/code&gt; repository. This helps us track changes we make and also makes a backup of the file in case we screw (sorry, mess) something up.&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Note 1:&lt;/strong&gt; To move easily between Emacs windows using the keyboard, just press &lt;code&gt;Shift&lt;/code&gt; and the arrow key pointing in the direction you want to move.
      &lt;strong&gt;Note 2:&lt;/strong&gt; To only show the current Emacs window - press: &lt;code&gt;C-x 1&lt;/code&gt;&lt;/p&gt;
      
      &lt;ol&gt;
          &lt;li&gt;Inside Emacs, press `C-x g` to run `magit-status` and enter the directory (note that `Tab` auto-completes): `~/.emacs.d`&lt;br&gt;
              &lt;img src=&quot;http://martin.elwin.com/blog/wp-content/uploads/2009/01/emacs-magit-status.png&quot; alt=&quot;Emacs magit-status&quot; title=&quot;Emacs magit-status&quot; width=&quot;694&quot; height=&quot;353&quot; class=&quot;alignnone size-full wp-image-114&quot; /&gt;
              &lt;/li&gt;
          &lt;li&gt;Put the cursor over the `&lt;em&gt;username&lt;/em&gt;.el` in the list of `Untracked files`.&lt;/li&gt;
          &lt;li&gt;Press `s` to Stage the new file - this adds the file to the Git staging area, from which all files are committed.&lt;br&gt;
      &lt;img src=&quot;http://martin.elwin.com/blog/wp-content/uploads/2009/01/emacs-magit-status-staged.png&quot; alt=&quot;Emacs magit-status staged&quot; title=&quot;Emacs magit-status staged&quot; width=&quot;694&quot; height=&quot;353&quot; class=&quot;alignnone size-full wp-image-115&quot; /&gt;
      &lt;/li&gt;
          &lt;li&gt;Press `d` and then accept to diff against HEAD - this will show you a diff view of the changes we have staged - just the add of a single file.&lt;br&gt;
      &lt;img src=&quot;http://martin.elwin.com/blog/wp-content/uploads/2009/01/emacs-magit-status-diff.png&quot; alt=&quot;Emacs magit-status diff&quot; title=&quot;Emacs magit-status diff&quot; width=&quot;757&quot; height=&quot;429&quot; class=&quot;alignnone size-full wp-image-116&quot; /&gt;
      &lt;/li&gt;
          &lt;li&gt;Press `c` to perform the commit. This opens a new buffer into which a commit message can be added.&lt;/li&gt;
          &lt;li&gt;Write something like: `Add personal configuration file.`&lt;/li&gt;
              &lt;li&gt;Now press `C-c C-c` to commit the file.&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;p&gt;That&#8217;s it - now the change has been committed to the local clone of the emacs-starter-kit Git repository.&lt;/p&gt;
      
      &lt;p&gt;To see the log of all commits, press &lt;code&gt;l&lt;/code&gt; (lowercase L) in the &lt;code&gt;magit-status&lt;/code&gt; buffer:&lt;br&gt;
      &lt;img src=&quot;http://martin.elwin.com/blog/wp-content/uploads/2009/01/emacs-magit-status-log.png&quot; alt=&quot;Emacs magit-status log&quot; title=&quot;Emacs magit-status log&quot; width=&quot;757&quot; height=&quot;429&quot; class=&quot;alignnone size-full wp-image-121&quot; /&gt;&lt;/p&gt;
      
      &lt;p&gt;To look at a certain commit - just press &lt;code&gt;Enter&lt;/code&gt; on it and a view of the diff will be shown. This makes it quite easy to browse through commits in a repository. At the top of the log is the most recent commit, which in this case is the file we just added.&lt;/p&gt;
      
      &lt;p&gt;To update emacs-starter-kit with the latest changes in the GitHub repository, just press &lt;code&gt;F&lt;/code&gt; in the &lt;code&gt;magit-status&lt;/code&gt; buffer or run &lt;code&gt;git pull&lt;/code&gt; in the &lt;code&gt;~/.emacs.d&lt;/code&gt; directory.&lt;/p&gt;
      
      &lt;h3&gt;Summary&lt;/h3&gt;
      
      &lt;p&gt;Now that we have Git and Emacs set up we can finally move to Ioke. In the next post we&#8217;ll go through installing the latest Java JDK and getting and compiling the Ioke source code.&lt;/p&gt;
      
      &lt;p&gt;Join me then!&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-4/&quot;&gt;Part 4: Java and Ant&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>The Hitchhiker&#8217;s Guide to an Ioke Dev Env From Source (part 1: Git)</title>
    <link href="http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-1/" />
    <updated>2009-01-12T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-1</id>
    <content type="html">
      &lt;p&gt;In this series of posts I will guide you, the humble reader, through the install procedure to get a development environment for &lt;a href=&quot;http://ioke.org/&quot;&gt;Ioke&lt;/a&gt; up and running. All the cool kids want to develop in Ioke nowadays, so let&#8217;s make you can as well!&lt;/p&gt;
      
      &lt;p&gt;The components we will be installing are:&lt;/p&gt;
      
      &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;http://git-scm.com/&quot;&gt;Git 1.6.1&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://www.gnu.org/software/emacs/&quot;&gt;Emacs (latest snapshot)&lt;/a&gt; with &lt;a href=&quot;http://github.com/technomancy/emacs-starter-kit/tree/master&quot;&gt;emacs-starter-kit&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://java.sun.com/&quot;&gt;Java JDK 1.6&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;http://ioke.org/&quot;&gt;Ioke (latest snapshot)&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      
      
      &lt;p&gt;These instructions are written for a non-expert who might not have too much experience with compiling things, using Git or Emacs. If you&#8217;re an expert you will find nothing new or exciting here! The environment I use is a freshly installed &lt;a href=&quot;http://www.kubuntu.org/&quot;&gt;Kubuntu Intrepid Ibex&lt;/a&gt; box, although most of it should be similar, if not identical, to other Ubuntu/Debian based distributions.&lt;/p&gt;
      
      &lt;p&gt;The components listed above will all be installed manually - not using the package system. This is to allow us to get the freshest versions of what we need without depending on the packages in the distribution to be updated (or hunted down in alternative repositories). The only thing we will install from the distribution are the compilers, tools and development libraries used to compile the software.&lt;/p&gt;
      
      &lt;p&gt;Why do we not use the package system? Well, that&#8217;s a valid question. Most of the above can be installed from packages in custom repositories. It&#8217;s simple and convenient. However here we will not use if for two reasons:&lt;/p&gt;
      
      &lt;ol&gt;
          &lt;li&gt;If packages are used we will depend on the repositories to be updated to use the latest version of some software, which can be annoying if we want to develop on the bleeding edge.&lt;/li&gt;
          &lt;li&gt;It&#8217;s good to know how to compile things yourself - so by not using prepared packages we might learn something!&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;p&gt;To keep control over our custom built software we&#8217;ll install it in dedicated directories under &lt;code&gt;$HOME/opt&lt;/code&gt; instead of in the normal locations like &lt;code&gt;/usr/bin&lt;/code&gt;. This allows us to get everything installed without needing root access (except to install the compilers etc from the distribution).&lt;/p&gt;
      
      &lt;h3&gt;First Step&lt;/h3&gt;
      
      &lt;h1&gt;Don&#8217;t Panic!&lt;/h1&gt;
      
      &lt;p&gt;Always sound advice to start with - especially if you are hitchhiking. I&#8217;m going to try to cover each step in detail, but if you think something is unclear - just leave a comment and I&#8217;ll try to clarify. So - grab your towel and let&#8217;s get going!&lt;/p&gt;
      
      &lt;h3&gt;Install Git&lt;/h3&gt;
      
      &lt;p&gt;For Emacs, emacs-starter-kit and Ioke we will use Git to retrieve the sources. Therefore the first thing we need to install is Git.&lt;/p&gt;
      
      &lt;p&gt;In the command line instructions below, all lines prefixed by the prompt &lt;code&gt;&amp;lt;dir&amp;gt;$&lt;/code&gt; are commands to be typed in. The rest are output or my comments.&lt;/p&gt;
      
      &lt;p&gt;Open a terminal window and create a new work directory under your home using the following instructions. In this directory we will work with downloaded source files and build the software.&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;mkdir ~/work
      ~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/work
      ~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;wget -O - http://kernel.org/pub/software/scm/git/git-1.6.1.tar.bz2 | tar xjv
      ... many lines...
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;The last command downloads the git source package and expands it in one go by piping it directly from &lt;code&gt;wget&lt;/code&gt; to &lt;code&gt;tar&lt;/code&gt;, which is told to expand it using bz2 with the &lt;code&gt;j&lt;/code&gt; parameter. This is a convenient way to get packages off the net and unpacked, especially when there is no need to keep the package itself around.&lt;/p&gt;
      
      &lt;p&gt;The result is that we now have a &lt;code&gt;git-1.6.1&lt;/code&gt; directory in the work directory. Let&#8217;s see how we compile it:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;git-1.6.1/
      ~/work/git-1.6.1&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;head INSTALL
      
                      Git installation
      
      Normally you can just &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;make&quot;&lt;/span&gt; followed by &lt;span class=&quot;s2&quot;&gt;&quot;make install&quot;&lt;/span&gt;, and that
      will install the git programs in your own ~/bin/ directory.  If you want
      to &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;a global install, you can &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      
              &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make &lt;span class=&quot;nv&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr all doc info ;&lt;span class=&quot;c&quot;&gt;# as yourself&lt;/span&gt;
              &lt;span class=&quot;c&quot;&gt;# make prefix=/usr install install-doc install-html install-info ;# as root&lt;/span&gt;
      
      ~/work/git-1.6.1&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;So - two commands. Simple enough! However, before we compile - we need to make sure all the relevant packages are installed:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work/git-1.6.1&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo apt-get install libcurl4-openssl-dev zlib1g-dev libexpat-dev tk8.5 asciidoc docbook2x
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Depending on your internet connection, this could take quite a while, as we need to download the &lt;code&gt;texlive&lt;/code&gt; distribution, among other things, to build all of the Git documentation. This is not strictly necessary, but here we&#8217;ll just do it for completeness&#8217; sake.&lt;/p&gt;
      
      &lt;p&gt;Let&#8217;s build git and make sure it&#8217;s installed under our &lt;code&gt;$HOME/opt&lt;/code&gt; directory as we said in the beginning:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work/git-1.6.1&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make &lt;span class=&quot;nv&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;~/opt/git-1.6.1 all doc info
      ... lots of lines...
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Compiling Git will take some time as well. Go get a coffee (or perhaps a &lt;a href=&quot;http://en.wikibooks.org/wiki/Bartending/Cocktails/Pan_Galactic_Gargle_Blaster&quot;&gt;Pan Galactic Gargle Blaster&lt;/a&gt; - sweet like nectar).&lt;/p&gt;
      
      &lt;p&gt;Once the compile is done - install it. Note that we don&#8217;t need to do this as &lt;code&gt;root&lt;/code&gt; as we&#8217;re installing under the user home directory:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work/git-1.6.1&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;make &lt;span class=&quot;nv&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;~/opt/git-1.6.1 install install-doc install-html install-info
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Let&#8217;s add it to the user&#8217;s path by linking it into the private &lt;code&gt;bin&lt;/code&gt; directory. This depends on the standard Ubuntu &lt;code&gt;bash&lt;/code&gt; shell profile script which adds &lt;code&gt;~/bin&lt;/code&gt; to the &lt;code&gt;PATH&lt;/code&gt; variable. If a different shell is used you need to perform the appropriate steps yourself.&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~/work/git-1.6.1&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;mkdir ~/bin
      ~/work/git-1.6.1&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; !&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;
      ~/bin&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ln -s ../opt/git-1.6.1/bin/git
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Now close the shell/terminal, open a new one - and try the &lt;code&gt;git&lt;/code&gt; command:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git --version
      git version 1.6.1
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;If you get the above output - great! You&#8217;re don! Sit back and relax for a bit before moving on to the next section.&lt;/p&gt;
      
      &lt;p&gt;However, if you don&#8217;t get the version output, but instead see the following message, review the previous instructions and make sure it works ok before continuing.&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#INCORRECT OUTPUT - SOMETHING WAS MISSED!&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;#GO BACK AND REVIEW&lt;/span&gt;
      ~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git                                                                                                                                                                                        
      The program &lt;span class=&quot;s1&quot;&gt;&#39;git&#39;&lt;/span&gt; is currently not installed.  You can install it by typing:                                                                                                                  
      sudo apt-get install git-core                                                                                                                                                                 
      -bash: git: &lt;span class=&quot;nb&quot;&gt;command &lt;/span&gt;not found
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;If you still can&#8217;t get it to work - drop me a comment!&lt;/p&gt;
      
      &lt;h3&gt;Git in 30 Seconds&lt;/h3&gt;
      
      &lt;p&gt;There are loads of good Git tutorials and information. You can find several on the &lt;a href=&quot;http://git-scm.com/documentation&quot;&gt;official Git page&lt;/a&gt; and at &lt;a href=&quot;http://github.com/guides/home&quot;&gt;GitHub&lt;/a&gt; (go sign up if you haven&#8217;t already, and &lt;a href=&quot;http://github.com/melwin&quot;&gt;fork me&lt;/a&gt;!).&lt;/p&gt;
      
      &lt;p&gt;Here is a quick run through of a few common Git commands you could try out with your freshly brewed cup of Git:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;
      ~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;mkdir gittest
      ~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;gittest/
      ~/gittest&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git init
      Initialized empty Git repository in /home/melwin/gittest/.git/
      ~/gittest&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;Test file! &gt; test.txt
      ~/gittest&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add test.txt
      ~/gittest&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit -m &lt;span class=&quot;s2&quot;&gt;&quot;Initial import.&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;root-commit&lt;span class=&quot;o&quot;&gt;)]&lt;/span&gt;: created 79c091d: &lt;span class=&quot;s2&quot;&gt;&quot;Initial import.&quot;&lt;/span&gt;
       1 files changed, 1 insertions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 0 deletions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;-&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
       create mode 100644 test.txt
      ~/gittest&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;Add line. &gt;&gt; test.txt
      ~/gittest&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git diff test.txt
      diff --git a/test.txt b/test.txt
      index 1cbaf90..3746f9e 100644
      --- a/test.txt
      +++ b/test.txt
      @@ -1 +1,2 @@
       Test file!
      +Add line.
      ~/gittest&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit -a -m &lt;span class=&quot;s2&quot;&gt;&quot;Add new line.&quot;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;master&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;: created b20f9a4: &lt;span class=&quot;s2&quot;&gt;&quot;Add new line.&quot;&lt;/span&gt;
       1 files changed, 1 insertions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;+&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, 0 deletions&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;-&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;If you can follow the above - great! First part finished. Next up is to install GNU Emacs from source and the emacs-starter-kit, which provides a decent default a set of configuration for Emacs.&lt;/p&gt;
      
      &lt;p&gt;Stay tuned!&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href=&quot;http://martin.elwin.com/blog/2009/01/the-hitchhikers-guide-to-an-ioke-dev-env-from-source-part-2/&quot;&gt;Part 2: Emacs&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Ioke Syntax Highlighter for GeSHi</title>
    <link href="http://martin.elwin.com/blog/2009/01/ioke-syntax-highlighter-for-geshi/" />
    <updated>2009-01-10T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2009/01/ioke-syntax-highlighter-for-geshi</id>
    <content type="html">
      &lt;p&gt;Speaking of Ioke - just added a syntax highlighter definition for GeSHi in my Ioke fork repository. The commit can be found here:&lt;/p&gt;
      
      &lt;p&gt;&lt;a href=&quot;http://github.com/melwin/ioke/commit/54cfd7e54de0be910385c6ec805693fd3ed4e294&quot;&gt;http://github.com/melwin/ioke/commit/54cfd7e54de0be910385c6ec805693fd3ed4e294&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;The keyword definitions I borrowed (read stole) from &lt;a href=&quot;http://sam.aaron.name/&quot;&gt;Sam Aaron&lt;/a&gt;&#8217;s TextMate bundle (also in the Ioke repository). As Sam just said in the #ioke on freenode: &#8220;what goes around comes around&#8221;. :)&lt;/p&gt;
      
      &lt;p&gt;Highlighting test:&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Simple JSON Parser in Ioke</title>
    <link href="http://martin.elwin.com/blog/2009/01/simple-json-parser-in-ioke/" />
    <updated>2009-01-10T00:00:00+01:00</updated>
    <id>http://martin.elwin.com/blog/2009/01/simple-json-parser-in-ioke</id>
    <content type="html">
      &lt;p&gt;After having enjoyed most of the days off over Christmas my fingers started itching - time to do some programming. Luckily around the same time I stumbled across &lt;a href=&quot;http://olabini.com/blog/category/ioke/&quot;&gt;Ola Bini&#8217;s posts on the Ioke language&lt;/a&gt;. As the &lt;a href=&quot;http://ioke.org/guide.html&quot;&gt;Ioke guide&lt;/a&gt; begins:&lt;/p&gt;
      
      &lt;blockquote&gt;
      Ioke is a general purpose language. It is a strongly typed, extremely dynamic, prototype object oriented language. It is homoiconic and it&#8217;s closest ancestors is Io, Smalltalk, Ruby and Lisp - but it&#8217;s quite a distance from all of them.
      &lt;/blockquote&gt;
      
      
      &lt;p&gt;So what does this all mean? It means it&#8217;s fun! The language syntax is very regular (although not quite as regular as lisp) - code is data, data is code and everything is a message. It&#8217;s also one of relatively few languages that provide macros similar to those in lisp. In Ioke this means that a message stream can be operated on (modified, transformed, etc) before it&#8217;s evaluated, using normal Ioke methods. Anyone who groks lisp should be familiar with the power this gives.&lt;/p&gt;
      
      &lt;p&gt;In Ioke, a chain of messages is separated by space, with the first message being sent to the current receiver and subsequent messages are sent to the result of the previous one. For instance, in the code&lt;/p&gt;
      
      &lt;p&gt;the text literal &#8220;ioke rocks&#8221; results in an internal message which creates a Text object. To this object the &lt;code&gt;upper&lt;/code&gt; messages is sent, which results in an upper case copy of the Text object is created. To this object the &lt;code&gt;println&lt;/code&gt; message is sent, which prints the upper case text to the console.&lt;/p&gt;
      
      &lt;p&gt;As the Ioke reader handles space separated tokens, it&#8217;s quite easy to create macros to process non Ioke code. As a learning exercise I decided to try to implement a &lt;a href=&quot;http://www.json.org/&quot;&gt;JSON&lt;/a&gt; parser. Nothing too fancy - and doesn&#8217;t even have to be secure - just enough to parse simple JSON into Ioke objects.&lt;/p&gt;
      
      &lt;p&gt;JSON is usually parsed in one of two ways - into custom objects/classes or into collections like dictionaries and arrays. For this exercise I decided to create Ioke dictionaries and arrays and I want the result to work like this:&lt;/p&gt;
      
      &lt;p&gt;Now, looking at JSON, it&#8217;s suspiciously similar to Ioke - [] is used for arrays, {} is used for &#8220;dictionaries&#8221;, comma separates entries, &#8221; quotes strings, etc. The main problem is the colon &#8220;:&#8221; used for separating keys and values in a dictionary. As Ioke is a dynamic language we can redefine how messages are handled. Instead of using colon to define symbols, we can redefine it to instead create pairs suitable for a dict:&lt;/p&gt;
      
      &lt;p&gt;&#8221;:&#8221; is originally defined on DefaultBehavior Literals, but in the JSON the &#8220;:&#8221; message is always sent to Text, so it&#8217;s enough to redefine it there.&lt;/p&gt;
      
      &lt;p&gt;This single redefinition allows us to parse JSON directly with the Ioke reader - very nice.&lt;/p&gt;
      
      &lt;p&gt;But&#8230; Redefining &#8220;:&#8221; for all Text objects is not really good (especially not when Ola adds concurrency constructs!). Another alternative would be to redefine how the text objects are created and create a new &#8220;:&#8221; cell just for our JSON text objects - but I never got this to work, as the internal:createText message works with a raw Java string, which I couldn&#8217;t work with in a macro/method&#8230;&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; With &lt;a href=&quot;http://github.com/olabini/ioke/commit/8af3954df7961b3f594c73db5059310469e45df5&quot;&gt;Ola&#8217;s recent commit&lt;/a&gt;, the previously described workaround can now be simplified to the following code.&lt;/p&gt;
      
      &lt;p&gt;Now the above redefinition of the &#8220;:&#8221; message can be used, but is visible only in the scope of a &lt;code&gt;let&lt;/code&gt;:&lt;/p&gt;
      
      &lt;p&gt;As can be seen, the Ioke macro functionality gives us nice control over how messages are handled, and the environment can be changed before the arguments are evaluated. I&#8217;m looking forward to the day when we have full Java interop and can use these powerful constructs to control Java code!&lt;/p&gt;
      
      &lt;p&gt;Source code to the above example is committed to my Ioke fork at: &lt;a href=&quot;git://github.com/melwin/ioke.git&quot;&gt;git://github.com/melwin/ioke.git&lt;/a&gt;&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
      
      &lt;p&gt;PS: The thing that confuses me the most: how the heck are you supposed to pronounce Ioke?&lt;/p&gt;
      
      &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Sam Aaron shared the fact that Ola pronounces it eye-oh-key in the following interview: &lt;a href=&quot;http://www.akitaonrails.com/2008/11/22/rails-podcast-brasil-qcon-special-ola-bini-jruby-ioke&quot;&gt;http://www.akitaonrails.com/2008/11/22/rails-podcast-brasil-qcon-special-ola-bini-jruby-ioke&lt;/a&gt;&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Caching Filter Queries with Coherence</title>
    <link href="http://martin.elwin.com/blog/2008/09/caching-filter-queries-with-coherence/" />
    <updated>2008-09-21T00:00:00+02:00</updated>
    <id>http://martin.elwin.com/blog/2008/09/caching-filter-queries-with-coherence</id>
    <content type="html">
      &lt;p&gt;A pretty nice thing that I recently tried with a customer was storing a query result in a query cache.&lt;/p&gt;
      
      &lt;p&gt;For instance, consider the following method:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Collection&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getByFilter1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;NamedCache&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CacheFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;entrySet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;A query is executed across all nodes containing cache data in a cluster. The filter acts on the &lt;em&gt;values&lt;/em&gt; in the cache, not the keys. And as all values are usually not available locally on every node the query needs to execute on the separate nodes.&lt;/p&gt;
      
      &lt;p&gt;The query above is correct, but not very efficient. In the above case we query and retrieve the data as well from the separate nodes. A more efficient way would be to only get the keys for the matching values from the nodes and then retrieve the values from the local near cache:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Collection&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getByFilter2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;NamedCache&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CacheFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;keySet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;However, in this case we still perform the query every time.&lt;/p&gt;
      
      &lt;p&gt;Now - the clever part. Not so much on my side, but the Coherence engineers have thought things through and made the Filter implementations have good hashCode and equals implementations. This together with the fact that they are serializable makes them possible to use as keys in a cache! Sweet! Without changing our method&#8217;s interface we can add a query cache so that each query only is performed once.&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Collection&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getByFilter3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;NamedCache&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CacheFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
      
          &lt;span class=&quot;n&quot;&gt;NamedCache&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queryC&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CacheFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCache&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.querycache&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;queryC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
      
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;keySet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;queryC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      
          &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Note that we only save the keys in the query cache. This to avoid having several caches with the same data. When near caching is used, getting the data for the keys can still be a local only operation. Compared to getting the data from the separate nodes it&#8217;s several orders of magnitude faster - depending on the usage patterns.&lt;/p&gt;
      
      &lt;p&gt;Of course if queries are different every time, the query cache will not help much. But in most high load applications the same data tends to be needed several times.&lt;/p&gt;
      
      &lt;p&gt;Additionally, the properties queried on should in most cases be indexed. This is important to avoid too much overhead when searching for an entry in a cache.&lt;/p&gt;
      
      &lt;p&gt;One thing to think about when adding query caches is: how is data updated?&lt;/p&gt;
      
      &lt;p&gt;As part of updating the value caches the query caches should preferably be emptied of the outdated cached queries. This could be done programmatically &#8220;manually&#8221; when the data is updated, or by hooking in code to clean the entries from the query cache using the map listener mechanism. The relevant code could do a query using the ContainsFilter.&lt;/p&gt;
      
      &lt;p&gt;To summarize: a little code can go a long way to improve performance without affecting the interface used by an application. Good when query heavy applications are adapted to use a distributed cache like Coherence.&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
    </content>
  </entry>
  <entry>
    <title>Scala Syntax Highlighting for WP</title>
    <link href="http://martin.elwin.com/blog/2008/06/scala-syntax-highlighting-for-wp/" />
    <updated>2008-06-30T00:00:00+02:00</updated>
    <id>http://martin.elwin.com/blog/2008/06/scala-syntax-highlighting-for-wp</id>
    <content type="html">
      &lt;p&gt;Writing the previous post I realized that the Wordpress plugin for syntax highligting I was using (Highlight Source Pro) didn&#8217;t support Scala.&lt;/p&gt;
      
      &lt;p&gt;Instead I tried the WP-Syntax plugin, but this didn&#8217;t support Symbol literals:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sym&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;-Symbol&quot;&gt;&#39;foobar&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Symbol is: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;-Symbol&quot;&gt;&#39;barfoo&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;This seems to be because of single quote being interpreted as a quotation character. A fix seems to be removing the single quote from the Geshi language definition file &lt;code&gt;scala.php&lt;/code&gt; in the &lt;code&gt;wp-syntax/geshi/geshi&lt;/code&gt; directory. While there one can also specify a regex for symbols and give them their own color:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sym&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;-Symbol&quot;&gt;&#39;foobar&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Symbol is: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sym&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;-Symbol&quot;&gt;&#39;barfoo&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Also check out the &lt;a href=&quot;https://lampsvn.epfl.ch/trac/scala/browser/scala-tool-support/trunk/src/geshi/scala.php&quot;&gt;&lt;code&gt;scala.php&lt;/code&gt; in the LAMP repository&lt;/a&gt; - it seems to add some additional keywords and other colors. I used this and made the changes described above.&lt;/p&gt;
      
      &lt;p&gt;Full new &lt;code&gt;scala.php&lt;/code&gt; for Geshi after the break.&lt;/p&gt;
      
      &lt;p&gt;&lt;!--more--&gt;&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&lt;?php&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt;/*************************************************************************************&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * scala.php&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * --------&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * Author: Geoffrey Washburn (washburn@acm.ogr)&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * Release Version: ???&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * Date Started: 2008/01/03&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * Scala language file for GeSHi.&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * CHANGES&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * -------&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * 2007/01/03&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   -  Created by copying the Java highlighter&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * TODO&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * -------------------------&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; * * Finish&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *************************************************************************************&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *     This file is part of GeSHi.&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   GeSHi is free software; you can redistribute it and/or modify&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   it under the terms of the GNU General Public License as published by&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   the Free Software Foundation; either version 2 of the License, or&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   (at your option) any later version.&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   GeSHi is distributed in the hope that it will be useful,&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   GNU General Public License for more details.&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   You should have received a copy of the GNU General Public License&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   along with GeSHi; if not, write to the Free Software&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; *&lt;/span&gt;
      &lt;span class=&quot;sd&quot;&gt; ************************************************************************************/&lt;/span&gt;
      
      &lt;span class=&quot;nv&quot;&gt;$language_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;LANG_NAME&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Scala&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;COMMENT_SINGLE&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;//&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;   &lt;span class=&quot;cm&quot;&gt;/* import statements are not comments! */&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;COMMENT_MULTI&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/*&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;*/&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;CASE_KEYWORDS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;GESHI_CAPS_NO_CHANGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;QUOTEMARKS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;&quot;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&quot;&quot;&quot;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;ESCAPE_CHAR&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;\\&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;KEYWORDS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;cm&quot;&gt;/* Scala keywords, part 1: control flow */&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;case&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;default&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;do&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;else&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;for&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;if&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;match&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;while&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;cm&quot;&gt;/* Scala keywords, part 2 */&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;return&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;throw&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;try&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;catch&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;finally&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;abstract&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;class&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;def&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;extends&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;final&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;forSome&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;implicit&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;import&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;lazy&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;new&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;object&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;override&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;package&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;private&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;protected&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;requires&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;sealed&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;super&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;this&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;trait&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;type&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;val&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;var&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;with&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;yield&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;cm&quot;&gt;/* Scala keywords, part 3: standard value types */&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;unit&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Unit&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;boolean&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Boolean&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;int&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Int&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Any&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;AnyVal&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Nothing&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;cm&quot;&gt;/* other reserved words in Scala: literals */&lt;/span&gt;
                              &lt;span class=&quot;cm&quot;&gt;/* should be styled to look similar to numbers and Strings */&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;false&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;null&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;true&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;cm&quot;&gt;/* Scala reference types */&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;AnyRef&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Null&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;List&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;String&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Integer&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Option&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Array&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      
                      &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;SYMBOLS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;:&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;*&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&amp;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;%&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;!&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&lt;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;?&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;_&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;=&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;=&gt;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;&lt;-&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&lt;:&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&lt;%&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&gt;:&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;#&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;@&#39;&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;CASE_SENSITIVE&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                      &lt;span class=&quot;nx&quot;&gt;GESHI_COMMENTS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;cm&quot;&gt;/* all Scala keywords are case sensitive */&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;STYLES&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;KEYWORDS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #b1b100;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #000000; font-weight: bold;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #993333;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #b13366;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #aaaadd;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;SYMBOLS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #FFAA00;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;COMMENTS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #808080; font-style: italic;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;s1&quot;&gt;&#39;MULTI&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #808080; font-style: italic;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;ESCAPE_CHAR&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #000099; font-weight: bold;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;BRACKETS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #66cc66;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;STRINGS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #ff0000;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;NUMBERS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #cc66cc;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;METHODS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #006600;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #006600;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;SCRIPT&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                      &lt;span class=&quot;s1&quot;&gt;&#39;REGEXPS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;color: #008000;&#39;&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;URLS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;&#39;&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;OOLANG&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;OBJECT_SPLITTERS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                      &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;.&#39;&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;REGEXPS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                     &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&#39;[a-zA-Z_][a-zA-Z0-9_]*&quot;&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;STRICT_MODE_APPLIES&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;GESHI_NEVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;SCRIPT_DELIMITERS&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s1&quot;&gt;&#39;HIGHLIGHT_STRICT_BLOCK&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                      &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      
      &lt;span class=&quot;cp&quot;&gt;?&gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
    </content>
  </entry>
  <entry>
    <title>Clustering Scala Actors with Oracle Coherence for Fun and Profit</title>
    <link href="http://martin.elwin.com/blog/2008/06/clustering-scala-actors-with-oracle-coherence/" />
    <updated>2008-06-30T00:00:00+02:00</updated>
    <id>http://martin.elwin.com/blog/2008/06/clustering-scala-actors-with-oracle-coherence</id>
    <content type="html">
      &lt;p&gt;[Disclaimer: I work for Oracle.]&lt;/p&gt;
      
      &lt;p&gt;Although I haven&#8217;t used it too much yet, Scala is definitely one of the languages I find most interesting right now. Many customers I work with are heavily Java focused, and getting a more flexible and powerful language with superb Java interoperability to use on the JVM feels very liberating. Now I just need to convince the customers that Scala is the future&#8230; :] But if &lt;a href=&quot;http://www.adam-bien.com/roller/abien/entry/java_net_javaone_which_programming&quot;&gt;Gosling likes it&lt;/a&gt; it must be good, right?&lt;/p&gt;
      
      &lt;p&gt;A few months ago Jonas Bonér wrote about how &lt;a href=&quot;http://jonasboner.com/2008/01/25/clustering-scala-actors-with-terracotta/&quot;&gt;Scala actors can be clustered with Terracotta&lt;/a&gt;. I really enjoyed the article and I think the idea of distributed, redundant actors is very appealing. The actor paradigm is a nice way of developing concurrent applications (see the intro in Jonas&#8217; blog entry for more info) and if we can liberate the actors from the confines of a single JVM and easily distribute them over multiple hosts - all the better.&lt;/p&gt;
      
      &lt;h3&gt;Clustering with Coherence&lt;/h3&gt;
      
      &lt;p&gt;I&#8217;m not going to compare Coherence and Terracotta here. In short, &lt;a href=&quot;http://www.oracle.com/technology/products/coherence/index.html&quot;&gt;Coherence&lt;/a&gt; provides, among other things, a distributed caching and code execution mechanism without single points of failure. Coherence can be downloaded for evaluation purposes from the Oracle web site.&lt;/p&gt;
      
      &lt;p&gt;The idea I wanted to try was to have Scala actors that store their state in the distributed Coherence cache and run as normal Scala actors on a single node in the cluster at a time. The node the actor runs on should be allocated by Coherence and if the node fails, the actor should be automatically started on another node with maintained state and without any lost messages.&lt;/p&gt;
      
      &lt;p&gt;Also, I wanted this to work as similarly to normal Scala actors as possible with compatibility between the two.&lt;/p&gt;
      
      &lt;h3&gt;The Result&lt;/h3&gt;
      
      &lt;p&gt;Before investigating the proof of concept solution, let&#8217;s look at the result and what it gives us.&lt;/p&gt;
      
      &lt;p&gt;Here&#8217;s a simple test application with a normal Scala actor. It uses the recommended way of creating actors with &lt;code&gt;actor { ... }&lt;/code&gt;:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;coherencetest1&lt;/span&gt;
      
      &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.util.Date&lt;/span&gt;
      
      &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.actors.Actor._&lt;/span&gt;
      
      &lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ActorTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      
          &lt;span class=&quot;n&quot;&gt;actor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
            
            &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Actor started.&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;react&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&gt;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; - Got ping: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Total pings: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      
                &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;When this code is run, a simple actor that sends a message to itself is created and started. It sleeps for 1 second to pace the execution and to simulate a task that takes time to perform (of course, normally you shouldn&#8217;t sleep in real actors as you tie up the thread).&lt;/p&gt;
      
      &lt;p&gt;When the code is run, the following is displayed:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;Actor started.
      Sun Jun 29 15:57:16 CEST 2008 - Got ping: 1 Total pings: 1
      Sun Jun 29 15:57:17 CEST 2008 - Got ping: 2 Total pings: 2
      Sun Jun 29 15:57:18 CEST 2008 - Got ping: 3 Total pings: 3
      Sun Jun 29 15:57:19 CEST 2008 - Got ping: 4 Total pings: 4
      Sun Jun 29 15:57:20 CEST 2008 - Got ping: 5 Total pings: 5
      Sun Jun 29 15:57:21 CEST 2008 - Got ping: 6 Total pings: 6
      ...
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;Nothing too fancy, but a decent test case for our actor distribution. An important aspect of this actor is that it defines a local variable &lt;code&gt;pings&lt;/code&gt; and prints a message in the initialization part, before the &lt;code&gt;loop&lt;/code&gt; and &lt;code&gt;react&lt;/code&gt;. The value of the local var must be maintained and the initialization code must only be run once, and not when an actor is started on a new node after a failure.&lt;/p&gt;
      
      &lt;p&gt;Let&#8217;s make it a distributed Actor:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;coherencetest1&lt;/span&gt;
      
      &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.util.Date&lt;/span&gt;
      
      &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.actors.coherence.CoActor._&lt;/span&gt;
      
      &lt;span class=&quot;nd&quot;&gt;@serializable&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DactorTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      
          &lt;span class=&quot;n&quot;&gt;dactor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
            
            &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Actor started.&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            
            &lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;react&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&gt;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; - Got ping: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; Total pings: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                
                &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      
                &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;What have we done here? Three things:&lt;/p&gt;
      
      &lt;ol&gt;
          &lt;li&gt;Import `scala.actors.coherence.CoActor._` instead of `scala.actors.Actor._`&lt;/li&gt;
          &lt;li&gt;Made the &lt;em&gt;application object&lt;/em&gt; serializable&lt;/li&gt;
          &lt;li&gt;Create the actor using `dactor { &#8230; }` instead of `actor { &#8230; }`&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;p&gt;The first point is simple - we need access to the new functionality, so we import the new CoActor object instead of the standard Actor object.&lt;/p&gt;
      
      &lt;p&gt;For number two - this is slightly nasty. If I interpret things correctly; as the code block created as a parameter to &lt;code&gt;react&lt;/code&gt; needs to be serializable (so that the actor can be distributed over the network), all enclosing types needs to be serializable. I struggled with this for a while and the only option seems to be creating a proper named serializable type&#8230; But since I want to be able to create an actor in-line, we need to do it this way.&lt;/p&gt;
      
      &lt;p&gt;For the last point - &lt;code&gt;dactor { ... }&lt;/code&gt; is simply the function used to create a distributed actor instead of a normal actor.&lt;/p&gt;
      
      &lt;p&gt;Let&#8217;s run it:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;2008-06-29 16:11:18.779 Oracle Coherence 3.3.1/389 &lt;Info&gt; (thread=main, member=n/a): Loaded operational configuration from resource &quot;jar:file:/opt/coherence-3.3.1/lib/coherence.jar!/tangosol-coherence.xml&quot;
      2008-06-29 16:11:18.785 Oracle Coherence 3.3.1/389 &lt;Info&gt; (thread=main, member=n/a): Loaded operational overrides from resource &quot;jar:file:/opt/coherence-3.3.1/lib/coherence.jar!/tangosol-coherence-override-dev.xml&quot;
      2008-06-29 16:11:18.786 Oracle Coherence 3.3.1/389 &lt;D5&gt; (thread=main, member=n/a): Optional configuration override &quot;/tangosol-coherence-override.xml&quot; is not specified
      
      Oracle Coherence Version 3.3.1/389
       Grid Edition: Development mode
      Copyright (c) 2000-2007 Oracle. All rights reserved.
      
      2008-06-29 16:11:19.042 Oracle Coherence GE 3.3.1/389 &lt;Info&gt; (thread=main, member=n/a): Loaded cache configuration from resource &quot;file:/crypt/dev/scala/CoherenceTest1/config/scalacoherence.xml&quot;
      2008-06-29 16:11:19.331 Oracle Coherence GE 3.3.1/389 &lt;Warning&gt; (thread=main, member=n/a): UnicastUdpSocket failed to set receive buffer size to 1428 packets (2096304 bytes); actual size is 714 packets (1048576 bytes). Consult your OS documentation regarding increasing the maximum socket buffer size. Proceeding with the actual value may cause sub-optimal performance.
      2008-06-29 16:11:19.459 Oracle Coherence GE 3.3.1/389 &lt;D5&gt; (thread=Cluster, member=n/a): Service Cluster joined the cluster with senior service member n/a
      2008-06-29 16:11:22.662 Oracle Coherence GE 3.3.1/389 &lt;Info&gt; (thread=Cluster, member=n/a): Created a new cluster with Member(Id=1, Timestamp=2008-06-29 16:11:19.343, Address=192.168.54.1:8088, MachineId=24065, Location=process:31397@dellicious, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=1) UID=0xC0A836010000011AD4A9DCAF5E011F98
      2008-06-29 16:11:22.834 Oracle Coherence GE 3.3.1/389 &lt;D5&gt; (thread=DistributedCache, member=1): Service DistributedCache joined the cluster with senior service member 1
      Actor started.
      Sun Jun 29 16:11:23 CEST 2008 - Got ping: 1 Total pings: 1
      Sun Jun 29 16:11:24 CEST 2008 - Got ping: 2 Total pings: 2
      Sun Jun 29 16:11:25 CEST 2008 - Got ping: 3 Total pings: 3
      Sun Jun 29 16:11:26 CEST 2008 - Got ping: 4 Total pings: 4
      Sun Jun 29 16:11:27 CEST 2008 - Got ping: 5 Total pings: 5
      Sun Jun 29 16:11:28 CEST 2008 - Got ping: 6 Total pings: 6
      ...
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;After the Coherence initialization (which happens automatically and which I&#8217;ve disabled in the outputs below) the actor starts up as expected. However, if we start this on two nodes - there will be two actors created, and no way for a new JVM to get hold of a reference to a specific existing actor. To handle this, let&#8217;s specify a name for the actor that we create using the &lt;code&gt;dactor(name : Symbol) { ... }&lt;/code&gt; function:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DactorTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      
          &lt;span class=&quot;n&quot;&gt;dactor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;pingActor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pings&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;This simply means: Give me a reference to &lt;code&gt;pingActor&lt;/code&gt;, but if it doesn&#8217;t exist - create it with the following body. This mechanism makes it easy to have a single instance of an actor even if the same application is running on multiple nodes, without having to explicitly check if an actor has already been created or not.&lt;/p&gt;
      
      &lt;p&gt;Now we can run the program on two different nodes. After the actor has started and is running on one node, I&#8217;ll kill that node:&lt;/p&gt;
      
      &lt;table&gt;
      &lt;tr valign=&quot;top&quot;&gt;
      &lt;td&gt;Node 1&lt;/td&gt;&lt;td&gt;Node 2&lt;/td&gt;&lt;/tr&gt;
      &lt;tr valign=&quot;top&quot;&gt;
      &lt;td&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;Actor started.
      Sun Jun 29 16:30:41 CEST 2008 - Got ping: 1 Total pings: 1
      Sun Jun 29 16:30:42 CEST 2008 - Got ping: 2 Total pings: 2
      Sun Jun 29 16:30:43 CEST 2008 - Got ping: 3 Total pings: 3
      Sun Jun 29 16:30:44 CEST 2008 - Got ping: 4 Total pings: 4
      Sun Jun 29 16:30:45 CEST 2008 - Got ping: 5 Total pings: 5
      Sun Jun 29 16:30:46 CEST 2008 - Got ping: 6 Total pings: 6
      Sun Jun 29 16:31:02 CEST 2008 - Got ping: 19 Total pings: 19
      Sun Jun 29 16:31:03 CEST 2008 - Got ping: 20 Total pings: 20
      Sun Jun 29 16:31:04 CEST 2008 - Got ping: 21 Total pings: 21
      Sun Jun 29 16:31:05 CEST 2008 - Got ping: 22 Total pings: 22
      Sun Jun 29 16:31:06 CEST 2008 - Got ping: 23 Total pings: 23
      Sun Jun 29 16:31:07 CEST 2008 - Got ping: 24 Total pings: 24
      Sun Jun 29 16:31:08 CEST 2008 - Got ping: 25 Total pings: 25
      Sun Jun 29 16:31:09 CEST 2008 - Got ping: 26 Total pings: 26
      Sun Jun 29 16:31:10 CEST 2008 - Got ping: 27 Total pings: 27
      Sun Jun 29 16:31:11 CEST 2008 - Got ping: 28 Total pings: 28
      ...
      &lt;/pre&gt;
      &lt;/div&gt;&lt;/td&gt;
      &lt;td&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;Sun Jun 29 16:30:47 CEST 2008 - Got ping: 6 Total pings: 6
      Sun Jun 29 16:30:48 CEST 2008 - Got ping: 7 Total pings: 7
      Sun Jun 29 16:30:49 CEST 2008 - Got ping: 8 Total pings: 8
      Sun Jun 29 16:30:50 CEST 2008 - Got ping: 9 Total pings: 9
      Sun Jun 29 16:30:51 CEST 2008 - Got ping: 10 Total pings: 10
      Sun Jun 29 16:30:53 CEST 2008 - Got ping: 11 Total pings: 11
      Sun Jun 29 16:30:54 CEST 2008 - Got ping: 12 Total pings: 12
      Sun Jun 29 16:30:55 CEST 2008 - Got ping: 13 Total pings: 13
      Sun Jun 29 16:30:56 CEST 2008 - Got ping: 14 Total pings: 14
      Sun Jun 29 16:30:57 CEST 2008 - Got ping: 15 Total pings: 15
      Sun Jun 29 16:30:58 CEST 2008 - Got ping: 16 Total pings: 16
      Sun Jun 29 16:30:59 CEST 2008 - Got ping: 17 Total pings: 17
      Sun Jun 29 16:31:00 CEST 2008 - Got ping: 18 Total pings: 18
      Sun Jun 29 16:31:01 CEST 2008 - Got ping: 19 Total pings: 19^C
      &lt;/pre&gt;
      &lt;/div&gt;&lt;/td&gt;
      &lt;/tr&gt;&lt;/table&gt;
      
      
      &lt;p&gt;First Node 1 started up and ran the actor until Node 2 started. At this point the actor was distributed to Node 2 (determined by the automatic cache partitioning done by Coherence) and started there. As can be seen, the local state (the total pings) was persisted and transferred over. When Node 2 was killed the actor was migrated back and started on Node 1. Note that the state of the actor is persisted for each message, so a sudden shutdown of a JVM is not a problem.&lt;/p&gt;
      
      &lt;p&gt;One might wonder why the message for ping number 6 and 19 can be seen in both outputs - this happens as the actor was migrated while the actor thread was sleeping - before the react body was complete. This causes the new node to rerun the message (since the processing of the message didn&#8217;t complete on the old node) and the support code in the old node makes sure all messages sent by the old actor are discarded as it&#8217;s been terminated. It&#8217;s a bit tricky coding actors to be fully idempotent as not everything is handled in a transaction, but limiting side effects to sending messages at the end of the processing makes it fairly reliable.&lt;/p&gt;
      
      &lt;p&gt;Here&#8217;s a slightly more complex example:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;coherencetest1&lt;/span&gt;
      
      &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.util.Date&lt;/span&gt;
      
      &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.actors.coherence.CoActor._&lt;/span&gt;
      
      &lt;span class=&quot;nd&quot;&gt;@serializable&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DactorTest2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;
          
          &lt;span class=&quot;n&quot;&gt;readLine&lt;/span&gt;
          
          &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numActors&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;
      
          &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actors&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&lt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numActors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dactor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;react&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&gt;&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; - Actor &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; got ping.&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;pong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          
          &lt;span class=&quot;n&quot;&gt;actors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;force&lt;/span&gt;
          
          &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pongs&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
          
          &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pongs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numActors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;pong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&gt;&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;pongs&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pongs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          
          &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Got &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pongs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; pongs.&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
          
          &lt;span class=&quot;n&quot;&gt;readLine&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;In this example 80 distributed actors are created and sent a ping message. After that the main thread receives all the pong replies. The output of this, when run on 4 nodes look like so:&lt;/p&gt;
      
      &lt;table&gt;
      &lt;tr valign=&quot;top&quot;&gt;
      &lt;td&gt;Node 1&lt;/td&gt;&lt;td&gt;Node 2&lt;/td&gt;&lt;/tr&gt;
      &lt;tr valign=&quot;top&quot;&gt;
      &lt;td&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;Sun Jun 29 09:19:34 CEST 2008 - Actor 1 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 12 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 15 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 18 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 22 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 25 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 27 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 29 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 41 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 42 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 47 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 50 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 54 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 56 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 61 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 75 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 79 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 80 got ping.
      Got 80 pongs.
      &lt;/pre&gt;
      &lt;/div&gt;&lt;/td&gt;
      &lt;td&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;Sun Jun 29 15:19:34 CEST 2008 - Actor 9 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 13 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 19 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 20 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 21 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 23 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 24 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 28 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 33 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 36 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 46 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 52 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 57 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 58 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 62 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 67 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 68 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 71 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 77 got ping.
      &lt;/pre&gt;
      &lt;/div&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr valign=&quot;top&quot;&gt;
      &lt;td&gt;Node 3&lt;/td&gt;&lt;td&gt;Node 4&lt;/td&gt;&lt;/tr&gt;
      &lt;tr valign=&quot;top&quot;&gt;
      &lt;td&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;Sun Jun 29 15:19:34 CEST 2008 - Actor 2 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 4 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 5 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 6 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 7 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 8 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 10 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 11 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 30 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 31 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 32 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 34 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 35 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 37 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 39 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 40 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 43 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 44 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 45 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 53 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 59 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 60 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 63 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 64 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 66 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 69 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 70 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 72 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 74 got ping.
      &lt;/pre&gt;
      &lt;/div&gt;&lt;/td&gt;
      &lt;td&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;Sun Jun 29 15:19:34 CEST 2008 - Actor 3 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 14 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 16 got ping.
      Sun Jun 29 15:19:34 CEST 2008 - Actor 17 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 26 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 38 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 48 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 49 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 51 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 55 got ping.
      Sun Jun 29 15:19:35 CEST 2008 - Actor 65 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 73 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 76 got ping.
      Sun Jun 29 15:19:36 CEST 2008 - Actor 78 got ping.
      &lt;/pre&gt;
      &lt;/div&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;/table&gt;
      
      
      &lt;p&gt;The program was started on all 4 nodes, but only the first node passes the first readLine. The other nodes just init the distributed actor framework and wait. As can be seen, the actors were distributed over the running nodes as expected - however, with small numbers like this the distribution can be a bit uneven (compare Node 3 and Node 4).&lt;/p&gt;
      
      &lt;h3&gt;The Solution&lt;/h3&gt;
      
      &lt;p&gt;The solution to allow the distribution of serializable actors is based on the Coherence backing map listeners. These can be used to get notifications of which specific node is the master for a certain object. As there only is one master for an object at any point, and a new master is allocated automatically if a master fails, we can use this to determine where the actor should run.&lt;/p&gt;
      
      &lt;p&gt;The object returned from &lt;code&gt;dactor { ... }&lt;/code&gt; is a Proxy object - very similar to the Proxy used in the standard Scala remote actors. In fact, this whole thing is built in a way similar to the standard Scala remote actors, with Proxy objects acting on behalf of the sender on the receiver side and receiver on the sender side.&lt;/p&gt;
      
      &lt;p&gt;Additionally, the Coherence grid invocation mechanism allows us to deliver messages to running actors directly to the node where it is running.&lt;/p&gt;
      
      &lt;p&gt;When a new dactor is created, the following happens:&lt;/p&gt;
      
      &lt;ol&gt;
          &lt;li&gt;`dactor { &#8230; }` creates a new anonymous `CoActor` class with the dactor body set as the `init` method.&lt;/li&gt;
          &lt;li&gt;The CoActor.distribute method is called which in turn saves the anonymous class instance to the Coherence cache. The object gets serialized when this happens. The key to the object in the cache is either the passed in symbol name, or a name created from a `java.util.UUID`&lt;/li&gt;
          &lt;li&gt;The `dactor` function returns a Proxy object with the name of the newly created distributed actor.&lt;/li&gt;
          &lt;li&gt;Meanwhile, in the node which Coherence designates the master of the object, the backing map listener gets an insert event and starts the actor.&lt;/li&gt;
          &lt;li&gt;The default `act()` method is called, which in a CoActor calls the `init` method first.&lt;/li&gt;
          &lt;li&gt;The `init` method contains the `dactor { &#8230; }` body, which gets executed.&lt;/li&gt;
          &lt;li&gt;The body executes as normally up until the `loop` block. `loop` in the CoActor first saves the body of the loop into a variable in CoActor so that it can continue executing just this body after it&#8217;s started in a new node, without running the initialization code again. After this the loop body is run as normal.&lt;/li&gt;
          &lt;li&gt;When `react` is hit, the thread breaks and the actor waits for incoming message using the normal actor scheduling mechanism.&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;p&gt;When a message is sent to a distributed actor using a Proxy object the following happens:&lt;/p&gt;
      
      &lt;ol&gt;
          &lt;li&gt;The message is sent using the Coherence invocation mechanism which transports the message to the master node where the cached actor runs.&lt;/li&gt;
          &lt;li&gt;In the master node, a Proxy actor representing the sender (which does not need to be a distributed actor) is created - this is because the actor framework always needs a sending actor which the receiver can reply to.&lt;/li&gt;
          &lt;li&gt;The sender Proxy is asked to send the actual message to the real distributed actor receiver.&lt;/li&gt;
          &lt;li&gt;The normal Scala actor framework handles the passing of the message and scheduling of the actors.&lt;/li&gt;
          &lt;li&gt;An overriden `send` in CoActor locks the actor and stores the message and a Save message in the mailbox.&lt;/li&gt;
          &lt;li&gt;The Save message gets the actor to first persist itself to the Coherence cache with the real message still in the mailbox. This is to ensure the message isn&#8217;t lost in case of a node failure.&lt;/li&gt;
          &lt;li&gt;After this the real message is processed by the actor and an overridden `react` saves the actor again after the message has been processed. This to update the cache with the new state of the actor.&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;p&gt;If the distributed actor does a &lt;code&gt;reply&lt;/code&gt; or sends a message to the &lt;code&gt;sender&lt;/code&gt;, the &lt;code&gt;Proxy&lt;/code&gt; which represents the non-distributed actor gets called as follows:&lt;/p&gt;
      
      &lt;ol&gt;
          &lt;li&gt;As the recevier (the original sender) isn&#8217;t a distributed actor handled by Coherence we cannot use the invocation mechanism. Instead the message is just put into a message cache.&lt;/li&gt;
          &lt;li&gt;A `MapListener` on every node checks to see if the newly inserted message in the message cache is intended for an actor running on that specific node.&lt;/li&gt;
          &lt;li&gt;If so, the message is deleted from the cache and delivered to the local actor through a Proxy representing the sender - just as in the previous case.&lt;/li&gt;
      &lt;/ol&gt;
      
      
      &lt;h3&gt;The Limitations&lt;/h3&gt;
      
      &lt;p&gt;The distributed actors are a bit limited in what they can do, as they always needs to be serializable and I didn&#8217;t want to change any of the standard Scala code. For instance - when a synchronous invocation is made the return channel is stored in the Scala actor. The return channel implementation used in Scala isn&#8217;t serializable, so I decided to not implement this feature for now.&lt;/p&gt;
      
      &lt;p&gt;Basically, only message sending (!), reply, sender, loop and react are allowed in the distributed actors. However, they can interoperate with normal actors as can be seen in this example:&lt;/p&gt;
      
      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distActor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dactor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;distActor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;react&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&gt;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&#39;pong&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          
          &lt;span class=&quot;n&quot;&gt;actor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;distActor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;-Symbol&quot;&gt;&#39;ping&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;react&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&gt;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Actor got message: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;/pre&gt;
      &lt;/div&gt;
      
      
      &lt;p&gt;The Proxy objects can be used by actors as they serialize correctly.&lt;/p&gt;
      
      &lt;h3&gt;The Conclusion&lt;/h3&gt;
      
      &lt;p&gt;Distributing (or GridEnabling(tm) or whatever the word &lt;em&gt;du jour&lt;/em&gt; is) actors to easily use the processing power and resilience multiple computers give but at the same time hiding the complexity from the developer is a nice way to fairly easily scale up an actors based application. To add more processing power or redundancy - just fire up new nodes.&lt;/p&gt;
      
      &lt;p&gt;The proof of concept I made here just scratches the surface, but it&#8217;s interesting to see that it can be done with Coherence while maintaining the syntax and behavior expected by Scala developers.&lt;/p&gt;
      
      &lt;h3&gt;The Source&lt;/h3&gt;
      
      &lt;p&gt;The highly experimental and hackish source code for the proof of concept is available in the git repository at:&lt;/p&gt;
      
      &lt;pre&gt;
      http://martin.elwin.com/git/scala-coherence.git
      &lt;/pre&gt;
      
      
      &lt;p&gt;Dependencies are Scala (2.7.1 recommended) and Oracle Coherence. There are some scripts for Linux which are trivial to adapt to other operating environments.&lt;/p&gt;
      
      &lt;p&gt;/M&lt;/p&gt;
    </content>
  </entry>
</feed>
