<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-11993899</atom:id><lastBuildDate>Tue, 02 Mar 2010 10:17:51 +0000</lastBuildDate><title>Richard's technical notes</title><description></description><link>http://blog.spiralarm.com/richard/</link><managingEditor>noreply@blogger.com (Richard)</managingEditor><generator>Blogger</generator><openSearch:totalResults>71</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-772983623240289637</guid><pubDate>Sun, 28 Feb 2010 18:29:00 +0000</pubDate><atom:updated>2010-03-02T10:17:52.064Z</atom:updated><title>This blog has moved</title><description>This blog has moved to &lt;a href="http://richard.dallaway.com/"&gt;http://richard.dallaway.com/&lt;/a&gt; or http://richard.dallaway.com/rss.xml if want the feed URL.  Sorry. Thanks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-772983623240289637?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2010/02/this-blog-has-moved.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-3091844515426276456</guid><pubDate>Fri, 29 Jan 2010 15:05:00 +0000</pubDate><atom:updated>2010-01-29T15:52:16.988Z</atom:updated><title>Scala in London in 2010</title><description>There's plenty of Scala and Lift events in London this year....&lt;br /&gt;&lt;br /&gt;The London Scala User Group (which you can learn about at &lt;a href="http://lsug.org"&gt;lsug.org&lt;/a&gt;) is running a free event every month of the year.    Last night &lt;a href="http://www.chuusai.com/"&gt;Miles&lt;/a&gt; gave &lt;a href="http://skillsmatter.com/event/java-jee/a-brief-introduction-to-scala-for-java-developers"&gt;an introduction to Scala for Java developers&lt;/a&gt;, and the slides are &lt;a href="http://www.chuusai.com/documents/2010-01/skillsmatter-20100128.pdf"&gt;available as a PDF&lt;/a&gt;.  Next month on Feb 8th, Colin is giving examples of &lt;a href="http://skillsmatter.com/event/cloud-grid/lsug-jan-10"&gt;re-writing Java classes in Scala and making your code lovely&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;On 8th March I'll be doing a "Getting Started with Lift" session, which you can sign up for at &lt;a href="http://skillsmatter.com/event/java-jee/getting-started-with-lift"&gt;the Skillsmatter site&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;There's also...&lt;br /&gt;&lt;ul&gt;&lt;li&gt; a &lt;a href="http://jaxlondon.com/conferences/trackssessions/?tid=1584"&gt;Scala day at JAX&lt;/a&gt; (22 Feb, with a LSUG.org pub meet after) &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Martin Odersky will be &lt;a href="http://functionalpx.ning.com/forum/topics/martin-odersky-scala-liftoff?xg_source=activity"&gt;giving a class in June&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; A Scala Lift-off event in September&lt;/li&gt;&lt;br /&gt;&lt;li&gt;...and there will probably be a &lt;a href="http://www.meetup.com/Londonjavacommunity/"&gt;London Java User Group&lt;/a&gt; Unconference at some point which will have a Scala element.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;If you want a peek at what the other LSUG events are being planned for the year, get a Google Wave account and search for the LSUG wave, but join the &lt;a href="http://www.meetup.com/london-scala/"&gt;London Scala User meetup.com group&lt;/a&gt; to be emailed the announcements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-3091844515426276456?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2010/01/scala-in-london-in-2010.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-5406420269200518882</guid><pubDate>Thu, 03 Dec 2009 13:37:00 +0000</pubDate><atom:updated>2009-12-03T13:51:49.468Z</atom:updated><title>Functional Programming Events</title><description>Next week I'll be heading up to the Skillsmatter &lt;a href="http://skillsmatter.com/event/design-architecture/functional-programming-exchange-2009/wd-407"&gt;Functional Programming Exchange&lt;/a&gt; event (Mon 7 December 2009).   I hoping to learn some good stuff there.  The following day there's a &lt;a href="http://upcoming.yahoo.com/event/4896155"&gt;BrightArray event&lt;/a&gt; where we're going to discuss the paper &lt;a href="http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html"&gt;Why Functional Programming Matters&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-5406420269200518882?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/12/functional-programming-events.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-7318208187702901303</guid><pubDate>Sun, 29 Nov 2009 10:03:00 +0000</pubDate><atom:updated>2009-11-29T11:12:07.805Z</atom:updated><title>London Java Community Unconference 1</title><description>&lt;a href="http://www.flickr.com/photos/d6y/4143401628/" title="Door by d6y, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2675/4143401628_4d9dca6f2c.jpg" width="500" height="375" alt="Door" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Congratulations to the organizers of the &lt;a href="http://www.meetup.com/Londonjavacommunity/"&gt;London Java Community&lt;/a&gt;: the first unconference was a success.&lt;br /&gt;&lt;br /&gt;IBM kindly hosted the event at their &lt;a href="http://www-304.ibm.com/jct01005c/isv/spc/southbank.html"&gt;Southbank building&lt;/a&gt;, and it's a great location for an unconference.  It has a set of rooms that are just the right size, but also has a central mingling point where you can meet and chat with people.  Possibly for the first time at a conference for me the gaps between the sessions were as useful as the sessions themselves.&lt;br /&gt;&lt;br /&gt;I ran a session to discuss what's stopping anyone from using Scala, especially in existing Java projects.  Kind of a negative title in some ways, but the point is that I don't see any technical reasons not too as the tool chain is there.  I was interested to hear other's experiences.  &lt;a href="https://docs.google.com/fileview?id=0B0EWEdbeorKeYWZhYzg4MGEtMGY2YS00NzVkLWIwOTYtMzFkMzA5YTY0Zjg5&amp;hl=en"&gt;The slides from my session&lt;/a&gt; are online, but they were really just put up to help kick start a discussion between the 19 people who were in the room. &lt;br /&gt;&lt;br /&gt;It tuns out there's a detailed Google &lt;a href=" http://3.ly/ljcuc1"&gt;Wave covering this&lt;/a&gt; and other sessions, but I'll list the main points that were discussed here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Learning: there seemed to be a reluctance to use Scala until you know "the Scala way" or understand functional styles. It does seem fair to say you'll get more benefit from adopting more of Scala, but I feel that you need to at least start using Scala to understand how it can improve what you do.  The point was made that you can start using Scala in a Java-like way (there's absolutely nothing wrong with that), and get some benefits today.&lt;/li&gt;&lt;li&gt;What are the benefits?  Aside from less code, code that is easier to understand (IMHO), increased developer joy or passion, I pointed to the previous session which covered The Bug of the Month which was a hairy threading-related issue: if you're doing anything with threads, you've probably got it wrong. The actors library in Scala can simplify concurrency.&lt;/li&gt;&lt;li&gt;Commercial support: There's no named organization backing Scala.  So where does the warm Sun, IBM, Oracle feeling come from for management?&lt;/li&gt;&lt;li&gt;What areas is Scala best applied to?  That is, what areas of Java would you prefer to use Scala for?  The honest answer is all areas.  There's no place where you'd prefer Java over Scala.&lt;/li&gt;&lt;li&gt;Selling to management: why take the risk?  I think it's a case of why miss the opportunity, if you can deliver more reliable results faster, and keep developers happy and engaged. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I suggested&amp;#8212;and it's not an original idea&amp;#8212;that unit testing might be a place to start as you can improve tests and gain experience.  I put an example of that in my slides that I ripped out of some production code just before the presentation.&lt;br /&gt;&lt;br /&gt;There were requests for more Scala resources (damn...perhaps I should have done an intro to Scala session too) so here are the resources I've found useful:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.scala-lang.org/"&gt;scala-lang.org&lt;/a&gt; - for downloads of Scala and a list of the published books.&lt;/li&gt;&lt;li&gt;&lt;a href="daily-scala.blogspot.com"&gt;http://daily-scala.blogspot.com/&lt;/a&gt; - short examples of idiomatic Scala.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.scala-lang.org/node/199#scala-user "&gt;Scala Users mailing lis&lt;/a&gt;, where you can ask questions.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;In the pub afterwards, there was a Scala corner where the London Scala User Group was reinvigorated.   The &lt;a href="http://lsug.org"&gt;lsug.org&lt;/a&gt; has been recovered and &lt;a href="http://skillsmatter.com/go/java-jee"&gt;Skillsmatter&lt;/a&gt; have kindly offered to host a monthly event, probably on a Wednesday, starting in Jan 2010.  Keep an eye on the LJC mailing list for news.&lt;br /&gt;&lt;br /&gt;You'll find &lt;a href="http://www.flickr.com/photos/d6y/sets/72157622896912200/"&gt;my photos of the event on Flickr&lt;/a&gt; and the hash tag on Twitter is &lt;a href="http://twitter.com/#search?q=ljcuc1"&gt;#ljcuc1&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-7318208187702901303?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/11/london-java-community-unconference-1.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-2094412974578178381</guid><pubDate>Mon, 09 Nov 2009 11:25:00 +0000</pubDate><atom:updated>2009-11-09T11:57:10.023Z</atom:updated><title>Great functional programming lectures</title><description>A few weeks back &lt;a href="http://www.chuusai.com/"&gt;Miles&lt;/a&gt; emailed the &lt;a href="http://www.brightarray.org/"&gt;BrightArray group&lt;/a&gt; with a link to Erik Meijer's Functional Programming Fundamentals lectures.  You can find them listed at channel9 tagged as &lt;a href="http://channel9.msdn.com/tags/C9+Lectures/"&gt;C9 Lectures&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm not planning to &lt;a href="http://book.realworldhaskell.org/read/"&gt;use Haskell for real&lt;/a&gt;, but I wanted to pass the links on because I'm finding the lectures really helpful for thinking about software.  Possibly for thinking in general.  &lt;br /&gt;&lt;br /&gt;Two practical points about the series: you don't have to install silverlight to watch them as there are links to other formats over on the right of the page.  And the slides can be found over &lt;a href="http://www.cs.nott.ac.uk/~gmh/book.html"&gt;at Graham Hutton's Programming in Haskell page&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;Oh, and don't forget to do the homework.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-2094412974578178381?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/11/great-functional-programming-lectures.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-3789343543127056118</guid><pubDate>Fri, 30 Oct 2009 15:46:00 +0000</pubDate><atom:updated>2009-10-31T09:55:45.637Z</atom:updated><title>Nov 28: London Java Unconference</title><description>On Sat Nov 28th 2009, I'll be at the London Java Community's Unconference at the IBM south bank building.  Not exactly sure what I'll contribute, but my current thinking is something around the area of approaches to adding Scala into existing Java projects.  &lt;br /&gt;&lt;br /&gt;Check out the details on the &lt;a href="http://upcoming.yahoo.com/event/4771491"&gt;Upcoming page&lt;/a&gt; or read more on the &lt;a href="http://londonjavacommunity.wordpress.com/2009/10/23/our-first-unconference/"&gt;LJC's blog post&lt;/a&gt;.  It's £20 to cover costs (any left-over money is put behind the bar :-), but hurry... when I last checked there were only 11 places left out of 50.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-3789343543127056118?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/10/nov-28-london-java-unconference.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-7640117141661963999</guid><pubDate>Mon, 21 Sep 2009 08:55:00 +0000</pubDate><atom:updated>2009-09-21T10:20:09.469+01:00</atom:updated><title>Setting the character encoding in Scala</title><description>The only reliable way we've found for setting the default character encoding for Scala is to set &lt;code&gt;$JAVA_OPTS&lt;/code&gt; before running your application:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ JAVA_OPTS="-Dfile.encoding=utf8" scala&lt;br /&gt;Welcome to Scala version 2.7.5.final [...]&lt;br /&gt;Type in expressions to have them evaluated.&lt;br /&gt;Type :help for more information.&lt;br /&gt;&lt;br /&gt;scala&gt; val x = "garçon"                                     &lt;br /&gt;x: java.lang.String = garçon&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Just trying to set &lt;code&gt;scala -Dfile.encoding=utf8&lt;/code&gt; doesn't seem to do it. Of course, you may not need this if your OS defaults to a sensible character encoding.  I'm lumbered with something called "MacRoman"...&lt;br /&gt;&lt;br /&gt;You'll also want to make sure your terminal is set to UTF-8 encoding, which on the Mac is Terminal -&gt; Preferences -&gt; Settings -&gt; Advanced -&gt; International.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-7640117141661963999?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/09/setting-character-encoding-in-scala.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-7010009679257021739</guid><pubDate>Thu, 17 Sep 2009 08:41:00 +0000</pubDate><atom:updated>2009-09-17T21:25:37.919+01:00</atom:updated><title>The Scala REPL is great for Java developers too</title><description>This post is for Java developers who have heard about Scala but, although it might sound interesting, are getting on with what they need to do in Java thankyouverymuch.&lt;br /&gt;&lt;br /&gt;If that's you, it's still worth &lt;a href="http://www.scala-lang.org/downloads"&gt;installing Scala&lt;/a&gt; because the command-line tool makes  noodling with Java a delight.  The tool in question is the REPL (&lt;a href="http://en.wikipedia.org/wiki/Read-eval-print_loop"&gt;read-eval-print-loop&lt;/a&gt;, a language shell).&lt;br /&gt;&lt;br /&gt;Two quick examples...  &lt;br /&gt;&lt;br /&gt;Let's say there's some API you're going to use, but you just can't quite remember the format of the return result. The REPL is a great way to quickly find out what you actually get.  Here's what I found out looking for the list of all &lt;code&gt;TimeZone&lt;/code&gt;s:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ scala&lt;br /&gt;Welcome to Scala version 2.7.5.final [...]&lt;br /&gt;Type in expressions to have them evaluated.&lt;br /&gt;Type :help for more information.&lt;br /&gt;&lt;br /&gt;scala&gt; import java.util.TimeZone&lt;br /&gt;import java.util.TimeZone&lt;br /&gt;&lt;br /&gt;scala&gt; TimeZone.getAvailableIDs()&lt;br /&gt;res2: Array[java.lang.String] = Array(Etc/GMT+12, Etc/GMT+11,&lt;br /&gt; MIT, Pacific/Apia, Pacific/Midway, Pacific/Niue, &lt;br /&gt; Pacific/Pago_Pago, Pacific/Samoa, US/Samoa, America/Adak,  &lt;br /&gt; America/Atka, Etc/GMT+10, HST, Pacific/Fakaofo, &lt;br /&gt; Pacific/Honolulu, Pacific/Johnston, Pacific/Rarotonga, &lt;br /&gt; Pacific/Tahiti, SystemV/HST10, US/Aleutian, US/Hawaii,  &lt;br /&gt; Pacific/Marquesas, AST, America/Anchorage, America/Juneau, &lt;br /&gt; A...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Most of the developers I know might do a double take at the results syntax but wouldn't have a problem reading that TimeZone.getAvailabeIDs() gives me back an array of strings like "Pacific/Tahiti".  No Scala knowledge required to make use of that tool (ok, I left the line-ending semi-colons out, but you can put them in if you like).&lt;br /&gt;&lt;br /&gt;Second example. Quick! Answer this: what does &lt;code&gt;String.split&lt;/code&gt; return if there are no matches to the pattern?  Not sure? Try it and see:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;scala&gt; "Pacific/Tahiti".split("/")&lt;br /&gt;res3: Array[java.lang.String] = Array(Pacific, Tahiti)&lt;br /&gt;&lt;br /&gt;scala&gt; "wibble".split("/")        &lt;br /&gt;res4: Array[java.lang.String] = Array(wibble)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Hope that's useful.   Don't miss that you have command history editing (arrow keys on my keyboard).&lt;br /&gt;&lt;br /&gt;If you want to do more take a look at &lt;a href="http://www.artima.com/scalazine/articles/steps.html"&gt;First Steps to Scala&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-7010009679257021739?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/09/scala-repl-is-great-for-java-developers.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-8818307200011810537</guid><pubDate>Thu, 23 Jul 2009 11:29:00 +0000</pubDate><atom:updated>2009-07-23T13:13:10.054+01:00</atom:updated><title>Using an existing Scala + Maven project in Eclipse</title><description>In case you're having problems using the&lt;a href="http://www.scala-lang.org/node/94"&gt; Scala IDE for Eclipse&lt;/a&gt; with Maven projects, here's what I do:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Generate the Eclipse project files from the shell: &lt;code&gt;mvn eclipse:eclipse&lt;/code&gt;. If you already have Eclipse .project files, you'll have to remove them first or &lt;code&gt;mvn eclipse:clean&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;In Eclipse, do a File -&gt; Import... and select "General -&gt; Existing Projects into Workspace", navigate to my maven project and select it.&lt;/li&gt;&lt;li&gt;This gives you a Scala project, but you'll need to enable Maven: right click on the root of the project in the Package Explorer in Eclipse, select Maven menu and enable.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The plugins I have look like this:&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/d6y/3748403229/" title="Eclipse installed software I'm using by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3505/3748403229_aae293cdd2.jpg" width="500" height="330" alt="Eclipse installed software I'm using" /&gt;&lt;/a&gt;&lt;br /&gt;...and it all works very well.  The Maven plugin is the &lt;a href="http://m2eclipse.codehaus.org/index.html"&gt;m2 one&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Troubleshooting: If that doesn't work first time for you: Project -&gt; Clean... is your friend.  If you're still having problems, a Refresh and Close Project followed by an Open project is good.  In the worst case, close the project, exit Eclipse, remove the .metadata folder (at your own risk), and restart.&lt;br /&gt;&lt;br /&gt;You might also want to check out the &lt;a href="http://lampsvn.epfl.ch/trac/scala/wiki/ScalaIDEForEclipse"&gt;Scala IDE for Eclipse wiki pages&lt;/a&gt; for how others use Maven.&lt;br /&gt;&lt;br /&gt;And for the record, I'm using a Mac (64bit, 10.5.7), with Maven 2.2.0 configured in Eclipse preferences to be an External installation (not the Embedded, but I don't know if that makes a difference or not), JDK 1.5, using Eclipse classic 3.4.2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-8818307200011810537?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/07/using-existing-scala-maven-project-in.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-650461732809208093</guid><pubDate>Sun, 17 May 2009 21:08:00 +0000</pubDate><atom:updated>2009-05-26T09:56:51.864+01:00</atom:updated><title>The Smileys in Scala</title><description>or: &lt;i&gt;a visual interpretation of some of the syntax of the Scala programming language, with the aim of providing an aide memoire.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The Happy Walrus &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;code&gt;: =&amp;gt;&lt;/code&gt;&lt;/h2&gt;&lt;br /&gt;(Yeah, I needed to include the : to make this work).&lt;br /&gt;&lt;br /&gt;"The &lt;a href="http://en.wikipedia.org/wiki/Walrus"&gt;walrus&lt;/a&gt; prefers shallow shelf regions and forages on the sea bottom." And like the walrus, in Scala the symbol for by name parameters allows the shallow surface parameter to forage deep inside your code.&lt;br /&gt;&lt;br /&gt;An example from &lt;a href="http://www.apress.com/book/view/9781430219897"&gt;Beginning Scala&lt;/a&gt; of a method that keeps appending the results of a block of code until the test is true:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;def bmap[T](test&lt;strong&gt;: =&gt;&lt;/strong&gt; Boolean)(block&lt;strong&gt;: =&amp;gt;&lt;/strong&gt; T): List[T] = {&lt;br /&gt; val ret = new ListBuffer[T]&lt;br /&gt; while (test) ret += block&lt;br /&gt; ret.toList&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Here we see two walruses, &lt;code&gt;test&lt;/code&gt; and &lt;code&gt;block&lt;/code&gt;, neither of which are evaluated as parameters until you dive into the body of the method.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The Scissors  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;code&gt;&amp;gt;:&lt;/code&gt;&lt;/h2&gt;&lt;br /&gt;Putting a lower bounds on a type is rather like cutting off the option of passing a subclass.  That is, anything to the left of the scissors in...&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;def doStuff[B &lt;strong&gt;&amp;gt;:&lt;/strong&gt; T](p: B) = ...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;... is snipped away if the type to the left is a subclass ("below") the type on the right. I find it helps to mentally rotate 90 degrees anti-clockwise to see the scissors cutting B if it's "below" T in the &lt;a href="http://www.scala-lang.org/node/128"&gt;class hierarchy&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Chapter 19 of &lt;a href="http://www.artima.com/shop/programming_in_scala"&gt;Programming in Scala&lt;/a&gt; has the details, as does 8.3 of &lt;a href="http://www.scala-lang.org/sites/default/files/linuxsoft_archives/docu/files/ScalaByExample.pdf"&gt;Scala By Example (PDF)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Let's wield the scissors, by considering a manager who can't handle detail: they can think about fruit and apples, but nothing more specific...&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;scala&gt; case class Fruit()&lt;br /&gt;defined class Fruit&lt;br /&gt;&lt;br /&gt;scala&gt; case class Apple() extends Fruit&lt;br /&gt;defined class Apple&lt;br /&gt;&lt;br /&gt;scala&gt; case class Pippin() extends Apple&lt;br /&gt;defined class Pippin&lt;br /&gt;&lt;br /&gt;scala&gt; class Manager[A &gt;: Apple]&lt;br /&gt;defined class Manager&lt;br /&gt;&lt;br /&gt;scala&gt; new Manager[Fruit]&lt;br /&gt;res2: Manager[Fruit] = Manager@3b2000a5&lt;br /&gt;&lt;br /&gt;scala&gt; new Manager[Apple]&lt;br /&gt;res3: Manager[Apple] = Manager@276c9124&lt;br /&gt;&lt;br /&gt;scala&gt; new Manager[Pippin]&lt;br /&gt;&lt;console&gt;:11: error: type arguments [Pippin] do not conform to class&lt;br /&gt; Manager's type parameter bounds [A &amp;gt;: Apple]&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;The Fussy Bird  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;code&gt;&amp;lt;:&lt;/code&gt;&lt;/h2&gt;&lt;br /&gt;When it comes to...&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;A &lt;strong&gt;&amp;lt;:&lt;/strong&gt; B  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;...the fussy bird knows that the morsel on the left is the special, tastier class when compared to the big old lump of class to the right.  In Scala it signifies an upper bound, that &lt;code&gt;A&lt;/code&gt; must be the same or a subtype  (specialism) of &lt;code&gt;B&lt;/code&gt;. And special means tasty, so no wonder she's got her beak and eyes pointing left towards the tasty class.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;scala&gt; case class Stuff()&lt;br /&gt;defined class Stuff&lt;br /&gt;&lt;br /&gt;scala&gt; case class Food() extends Stuff&lt;br /&gt;defined class Food&lt;br /&gt;&lt;br /&gt;scala&gt; case class TastyFood() extends Food&lt;br /&gt;defined class TastyFood&lt;br /&gt;&lt;br /&gt;scala&gt; def peck[A &amp;lt;: Food](p: A) = println("yum")&lt;br /&gt;peck: [A &amp;lt;: Food](A)Unit&lt;br /&gt;&lt;br /&gt;scala&gt; peck(Food())&lt;br /&gt;yum&lt;br /&gt;&lt;br /&gt;scala&gt; peck(TastyFood())&lt;br /&gt;yum&lt;br /&gt;&lt;br /&gt;scala&gt; peck(Stuff())&lt;br /&gt;&lt;console&gt;:10: error: inferred type arguments [Stuff] do not conform&lt;br /&gt;  to method peck's type parameter bounds [A &amp;lt;: Food]&lt;br /&gt;       peck(Stuff())&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The bird is so fussy she'll even be happy with &lt;code&gt;Nothing&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;So that's the three I've had to work to remember. I hope I've got that far enough in the direction of correct to be useful. Someone will have to sort out stories for &lt;code&gt;&amp;lt;%&lt;/code&gt; (view bounds) and the rest of the syntax you might see such as &lt;code&gt;/:&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-650461732809208093?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/05/smileys-in-scala.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-6112254873955526290</guid><pubDate>Sun, 10 May 2009 18:35:00 +0000</pubDate><atom:updated>2009-05-11T22:11:39.290+01:00</atom:updated><title>Still loving the Scala</title><description>The other night I sat down to satisfy just one more quick-fix screen-scraping twitter-based itch. Of course I decided to scratch using Scala, and it really is an attractive language for "doing stuff".  It also made me reflect on how Scala has already started to changed the way I write software.&lt;br /&gt;&lt;br /&gt;Here's the itch: If you live in the centre of the pebble-beach city of Brighton, and have a dog, the tide times become really interesting, because at low tide sand is revealed, and &lt;a href="http://www.flickr.com/photos/janed/sets/72157617444708930/"&gt;sand is fantastic to play fetch in&lt;/a&gt;. You can get &lt;a href="http://www.visitbrighton.com/site/tourist-information/tide-timetables"&gt;Brighton tide times from VisitBrighton.com&lt;/a&gt;, but of course I want the information at the point I'm going to use it.  And for me, that means I want a tweet at 6:30 every morning.  And so, &lt;a href="http://twitter.com/brightontide"&gt;@brightontide&lt;/a&gt; was born (I'm still chatting about copyright with the council, so it might have to disappear).&lt;br /&gt;&lt;br /&gt;The problem could be boiled down to curl -&gt; grep/sed/awk -&gt; curl, but there's the added complication that tide times are in GMT, and I want to tweet them corrected for daylight saving.   &lt;br /&gt;&lt;br /&gt;So with that background out of the way, here we go...&lt;br /&gt;&lt;br /&gt;In essence I want to get the tide times for a given date:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;trait TideSource { &lt;br /&gt; def lowsFor(day:LocalDate): List[Tide]&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I'm using the &lt;a href="http://joda-time.sourceforge.net/"&gt;Joda Time&lt;/a&gt; classes &lt;code&gt;LocaDate&lt;/code&gt; and &lt;code&gt;LocalTime&lt;/code&gt; to represent a date (without time) and a time (without a date).  The &lt;code&gt;Tide&lt;/code&gt; class is just a wrapper for the time and height of the tide, plus the method for converting the time into the right timezone:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;case class Tide(when:LocalTime, height:Metre) {&lt;br /&gt;  &lt;br /&gt; override val toString = when.toString("HH:mm") + &lt;br /&gt;   " (" + height + ")"   &lt;br /&gt;&lt;br /&gt; def forZone(destZone:DateTimeZone) = &lt;br /&gt;   Tide( when.toDateTimeToday(DateTimeZone.forID("GMT")).&lt;br /&gt;    withZone(destZone).toLocalTime(), height)  &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Next I need to implement a &lt;code&gt;TideSource&lt;/code&gt; and, until I find something less hacky, that will be an implementation that scrapes the data from VisitBrighton.com.  I want to use it like this:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;val tide_times = VisitBrightonScraper.lowsFor(today)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Here's the code to allow that:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;object VisitBrightonScraper extends VisitBrightonScraper &lt;br /&gt;&lt;br /&gt;class VisitBrightonScraper extends TideSource {&lt;br /&gt;&lt;br /&gt; def page = Source.fromURL(&lt;br /&gt;  "http://www.visitbrighton.com/site/tourist-information/tide-timetables").mkString&lt;br /&gt;&lt;br /&gt; override def lowsFor(day:LocalDate) = {&lt;br /&gt;    &lt;br /&gt;  // We want the times that start with the date in this&lt;br /&gt;  // format: 10th May 2009&lt;br /&gt;  val date = day.ordinal + &lt;br /&gt;   DateTimeFormat.forPattern(" MMM yyyy").print(day); &lt;br /&gt;  &lt;br /&gt;  val Pattern = &lt;br /&gt;   """|(?sm).*&amp;lt;div class="TidalDataEntry"&amp;gt;&amp;lt;h3&amp;gt;DATE&amp;lt;/h3&amp;gt;&amp;lt;table class="TidalData"&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;       |&amp;lt;th&amp;gt;&amp;nbsp;&amp;lt;/th&amp;gt;&amp;lt;th class="Time"&amp;gt;Time&amp;lt;/th&amp;gt;&amp;lt;th class="Height"&amp;gt;Height .m.&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;       |&amp;lt;td class="Tide"&amp;gt;High&amp;lt;/td&amp;gt;&amp;lt;td class="Time"&amp;gt;(.+?)&amp;lt;/td&amp;gt;&amp;lt;td class="Height"&amp;gt;(.+?)&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;       |&amp;lt;td class="Tide"&amp;gt;Low&amp;lt;/td&amp;gt;&amp;lt;td class="Time"&amp;gt;(.+?)&amp;lt;/td&amp;gt;&amp;lt;td class="Height"&amp;gt;(.+?)&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;       |&amp;lt;/table&amp;gt;&amp;lt;/div&amp;gt;.*""".stripMargin&lt;br /&gt;          .replaceAll("\n","").replaceFirst("DATE", date).r&lt;br /&gt;&lt;br /&gt;  try  {&lt;br /&gt;   val Pattern(high_times,high_heights,low_times,low_heights) = page&lt;br /&gt;&lt;br /&gt;   // The times and heights are in separate columns;&lt;br /&gt;   // multiple values separated by "&amp;lt;br/&amp;gt;"&lt;br /&gt;   val tides = for ( (time_string,height) &amp;lt;- &lt;br /&gt;    low_times.split("&amp;lt;br/&amp;gt;") zip low_heights.split("&amp;lt;br/&amp;gt;") )&lt;br /&gt;    yield &lt;br /&gt;     Tide( time_string.toLocalTime, Metre(height.toDouble) )&lt;br /&gt;&lt;br /&gt;   tides.toList&lt;br /&gt;  }&lt;br /&gt;  catch {&lt;br /&gt;   case x:scala.MatchError =&gt; println(x)&lt;br /&gt;   Nil &lt;br /&gt;  } &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt; &lt;br /&gt;(Yuck. I have to find a better way to format code on this blog)&lt;br /&gt;&lt;br /&gt;There's nothing particularly exciting in any of this, but there are a couple of things that surprised me.  The first is the &lt;code&gt;zip&lt;/code&gt; function, which I distinctly remember reading about and thinking at the time: "nice, but there's no practical application I'll write that will ever need that" :-) But here we are, with a page layout where I have two columns of numbers that need to be paired up: exactly what zip does, and it saved me a couple of loops.&lt;br /&gt;&lt;br /&gt;The regular expression is a bit hairy.  You can figure out what's going on if you view the source of the page:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/d6y/3522644419/" title="Screen Scraping Target by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3297/3522644419_a88ab9b33b.jpg" width="500" height="452" alt="Screen Scraping Target" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But that code is going to need a unit test.  But how to "mock out" the HTTP request?  In Java, I probably would have separated things more so I supply the content of the HTTP request to another method that processes it.  Or maybe I'd have a factory to supply something that can fetch the HTML; or perhaps I'd use dependency injection.... but this is a quick script, to do a hacky job... but I do want to test it.  It turned out to be so very easy:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;object MockScraper extends VisitBrightonScraper {&lt;br /&gt; override def page = Source.fromFile(&lt;br /&gt;  "src/test/resources/visitbrighton07052009.html", &lt;br /&gt;  "UTF-8").mkString&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Nothing you can't do in Java, but here it feels so concise and easy that it something that becomes usable for a unit test. &lt;br /&gt;&lt;br /&gt;Here's the corresponding test code that uses this test scraper:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;object VisitBrightonScraperSpec extends Specification {&lt;br /&gt;&lt;br /&gt; "Visit Brighton screen scraper" should {&lt;br /&gt;     &lt;br /&gt;  "locate low tide in first day" in { &lt;br /&gt;   &lt;br /&gt;   val tides = MockScraper.lowsFor(new LocalDate(2009, 5, 7))&lt;br /&gt;   tides.length must be_==(2)&lt;br /&gt;&lt;br /&gt;   val expected = List( Tide(new LocalTime(3,38), Metre(1.0)), &lt;br /&gt;    Tide(new LocalTime(15,59), Metre(1.0)) )&lt;br /&gt;      &lt;br /&gt;   tides must be_==(expected)&lt;br /&gt; }&lt;br /&gt; // etc&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Putting it together, you get:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;object TideTweet {&lt;br /&gt;&lt;br /&gt; def main(args:Array[String]) {&lt;br /&gt;&lt;br /&gt;  val today = new LocalDate&lt;br /&gt;&lt;br /&gt;  // Time tides are in GMT, but we will later convert to&lt;br /&gt;  // whatever timezone we're in:&lt;br /&gt;  val tz = DateTimeZone.getDefault&lt;br /&gt;     &lt;br /&gt;  val gmt_tides = VisitBrightonScraper.lowsFor(today) &lt;br /&gt;     &lt;br /&gt;  val tweet = gmt_tides match {&lt;br /&gt;   case Nil =&gt; "Gah! Failed to find tide times today.... Help!"&lt;br /&gt;   case tides =&gt; today.toString("'Low tides for 'EE d MMM': '") +&lt;br /&gt;    tides.map(_.forZone(tz)).mkString(", ")&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  println(tweet)&lt;br /&gt;     &lt;br /&gt;  if (args contains "-dotweet")&lt;br /&gt;   send(tweet)&lt;br /&gt;     &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I've skipped some of the details: you can download a &lt;a href="http://blog.spiralarm.com/richard/2009/05/tidetimes.tar.gz"&gt;tar.gz of the source&lt;/a&gt; if you're interested.&lt;br /&gt;&lt;br /&gt;This isn't exactly great code (error states returning &lt;code&gt;Nil&lt;/code&gt;? Twitter passwords baked into the source?) but it was an absolute joy and pleasure to write it in Scala.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-6112254873955526290?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/05/still-loving-scala.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>9</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-7190268748841209615</guid><pubDate>Thu, 05 Feb 2009 20:09:00 +0000</pubDate><atom:updated>2009-02-06T15:42:50.983Z</atom:updated><title>Scala &amp; Wicket London Meet Up</title><description>&lt;a href="http://www.flickr.com/photos/d6y/sets/72157613337804819/" title="Features include... by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3337/3254539728_705730ae7d.jpg" width="500" height="375" alt="Features include..." /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I know next to nothing about the &lt;a href="http://wicket.apache.org/"&gt;Wicket&lt;/a&gt; web framework, but I was intrigued by the &lt;a href="http://jweekend.com/"&gt;jWeekend&lt;/a&gt; &lt;a href="http://londonwicket.org/"&gt;London Wicket User's Group&lt;/a&gt; meet up last night.  The topic was "Scala and Wicket".&lt;br /&gt;&lt;br /&gt;As far as Scala and web frameworks go, the main name is &lt;a href="http://liftweb.net/"&gt;Lift&lt;/a&gt;.  The problem with Lift... No, let me re-phrase that because it's not a problem with Lift.  The great thing about Lift is that it's made for Scala, so it's going a great fit to the language.  Learning Lift and Scala at the same time should mean you're bouncing the framework learning and the language learning off each other, which is going to teach you a lot.&lt;br /&gt;&lt;br /&gt;Then again... if you're learning the language and trying to get your head around a framework, it seems to make the goal of "doing something useful with Scala" just that little bit further away.  So how about this: Scala and Java work well together, so why not use a web framework you already know, but just use Scala instead of Java?  Start gently, then, when ready, take a look a Lift.  &lt;br /&gt;&lt;br /&gt;I don't know which approach is best, but it seems there might be something in the gently-gently approach. There is one other compelling reason for looking at a existing (legacy? :-) web framework: you can dig into the publications on the topic, such as &lt;a href="http://www.manning.com/dashorst/"&gt;Wicket in Action&lt;/a&gt;, or &lt;a href="http://oreilly.com/catalog/9780596006518/"&gt;Programming Struts&lt;/a&gt;, or &lt;a href="http://oreilly.com/catalog/9780596006518/"&gt;Stripes&lt;/a&gt; etc. (Obviously this situation will change for Lift: I've already expressed my disappointment that none of the big publishers are looking at the practical aspects of Scala, but there is the start of &lt;a href="http://github.com/tjweir/liftbook/tree/master"&gt;a creative commons text&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;Sure, you're not necessarily going to learn Scala idioms from a non-Scala framework, and you're going to run into head-scratching issues, but it seems somehow more manageable to at least try it. More so if you're inserting Scala into an existing project.&lt;br /&gt;&lt;br /&gt;Of course, the whole argument falls apart for me in the case of this event, as I don't know Wicket :-)  But I've tried Scala in a trivial way with a large existing Struts 1 application, and it was surprisingly painless.&lt;br /&gt;&lt;br /&gt;But back to the event and the talks:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://stuq.nl"&gt;Daan van Etten&lt;/a&gt; gave a lovely "Basic Introduction to Scala With Wicket".  The &lt;a href="http://stuq.nl/weblog/2009-02-04/download-the-basic-and-wicket-scala-talk-materials"&gt;slides, handouts and code are available&lt;/a&gt;. One download and two commands to get the example app up and running was pleasing.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.imdplc.com/"&gt;Dean Phersson-Chapman&lt;/a&gt; spoke about his "Experiences Converting an Existing Wicket Application To Scala".  It seems there are some serialization issues between Wicket and Scala 2.7.3 which are being fixed.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.footprint.de/fcc/"&gt;Jan Kriesten&lt;/a&gt; showed examples of "Real World Scala and Wicket".  If you'd not seen Scala before, this was probably pretty scary stuff in places.  Jan clearly knows his Scala and his Wicket very well.&lt;/li&gt;&lt;li&gt;Finally, &lt;a href="http://herebebeasties.com/"&gt;Alastair Maw&lt;/a&gt; spoke about the evils of abstraction, which had some fine points about  when to avoid it (mostly) and when to embrace it (rarely).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;It looks like slides appear over at &lt;a href="http://londonwicket.org/"&gt;londonwicket.org&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-7190268748841209615?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/02/scala-wicket-london-meet-up.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-3531345578708024771</guid><pubDate>Thu, 22 Jan 2009 13:01:00 +0000</pubDate><atom:updated>2009-01-22T13:13:58.132Z</atom:updated><title>Four Scala Books</title><description>In addition to the completed and shipping &lt;a href="http://www.artima.com/shop/programming_in_scala"&gt;Programming in Scala&lt;/a&gt; book from Artima, there are three others in the works:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://pragprog.com/titles/vsscala/programming-scala"&gt;Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine&lt;/a&gt; from Pragmatic Programmers&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.al3x.net/2008/10/im-writing-book.html"&gt;Programming Scala&lt;/a&gt; from O'Reilly&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.lostlake.org/index.php?/archives/88-Announcing-Beginning-Scala.html"&gt;Beginning Scala&lt;/a&gt; from APress.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Great news.  &lt;br /&gt;&lt;br /&gt;If I'm going to be picky, I'd say I'm a little concerned all these look like they are language books, rather than "activity books".  What I mean by that is there's no "Database Persistence using Scala" or "Building Fast Web Sites Quickly with Scala" or "Asynchronous Messaging with Scala"... you get the idea.  Sure, you can just get on and use the Java way, but the idiomatic Scala approach is what I'm looking for.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-3531345578708024771?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/01/four-scala-books.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-4620615739801903503</guid><pubDate>Wed, 14 Jan 2009 20:32:00 +0000</pubDate><atom:updated>2009-01-25T10:48:22.563Z</atom:updated><title>The 'Hull City Problem' in Scala</title><description>&lt;a href="http://www.flickr.com/photos/d6y/3197691536/" title="Odd one out by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3092/3197691536_8dbe690d07.jpg" width="471" height="423" alt="Odd one out" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now that I have a physical copy of &lt;a href="http://www.artima.com/shop/programming_in_scala"&gt;Programming in Scala&lt;/a&gt; next to me, the final excuse for me not spending more time with the language has gone.  In the interest of dipping my toe in the language (well, it's more like my whole leg by now) I'm making a conscious effort to do all and any scripty things I have to do in Scala. &lt;br /&gt;&lt;br /&gt;One such script-like thing is the 'Hull City problem'. It's actually a very simple problem, and now I think about it, it's more an assertion than a problem: &lt;a href="http://en.wikipedia.org/wiki/Hull_City_A.F.C."&gt;Hull City&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Association_football"&gt;football&lt;/a&gt; club is the only club name in the &lt;a href="http://en.wikipedia.org/wiki/List_of_football_clubs_in_England"&gt;English league&lt;/a&gt; that cannot be coloured in.  &lt;br /&gt;&lt;br /&gt;By which I mean, if you look at a name like "Liverpool", it is made up of letters that are fully enclosed.  If you were doodling you could colour in the "o"s, the "p"s and the top of the "e".  You can't do that with "Hull City". Not in title case, not in upper case and not in lower case.  There's no other club in the league that you can say that about. &lt;br /&gt;&lt;br /&gt;Or can you?&lt;br /&gt;&lt;br /&gt;Clubs come and go, and even change name, so it'd be handy to have a script that could test that the assertion is still true.  Here's how I went about it in Scala, once I'd decided it was partly a regular expression problem.  Yes, regular expressions are my &lt;a href="http://en.wikipedia.org/wiki/Golden_hammer"&gt;hammer&lt;/a&gt; of choice.&lt;br /&gt;&lt;br /&gt;Although not really necessary for this problem, I defined a class for the name of the club and the level in the league (e.g., 1 is the Premier League; 12 is Gloucester Northern Senior League), and a method for deciding if the name can be coloured in:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;class Club(val name:String, val level:Int) &lt;br /&gt;{&lt;br /&gt; val failChars = "&amp;ABDOPQRabdegopq"&lt;br /&gt;  &lt;br /&gt; // We're given team names in Title Case, so that's what we &lt;br /&gt; // check here. The name can be coloured in if there exists &lt;br /&gt; // a character in the name that is contained in the list &lt;br /&gt; // of "fail characters". &lt;br /&gt; def canBeColouredIn = name.exists(c =&gt; failChars.contains(c))   &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;That seems OK:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ scalac Club.scala &lt;br /&gt;$ scala&lt;br /&gt;Welcome to Scala version 2.7.2.final [...]&lt;br /&gt;Type in expressions to have them evaluated.&lt;br /&gt;Type :help for more information.&lt;br /&gt;&lt;br /&gt;scala&gt; val hull = new Club("Hull City", 1)&lt;br /&gt;hull: Club = Club@bc9065&lt;br /&gt;&lt;br /&gt;scala&gt; hull.canBeColouredIn&lt;br /&gt;res0: Boolean = false&lt;br /&gt;&lt;br /&gt;scala&gt; new Club("Liverpool", 1).canBeColouredIn&lt;br /&gt;res1: Boolean = true&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;To try this on all clubs you need to &lt;a href="http://en.wikipedia.org/w/index.php?title=Special:Export&amp;pages=List+of+football+clubs+in+England"&gt;export the list of teams from Wikipedia&lt;/a&gt;, which gives you an XML file that contains a list of club names in a Wiki markup text format.  A line in that file looks like this: &lt;code&gt;|[[Aveley F.C.|Aveley]]||[[Isthmian League]] [[Isthmian League Division One North|Division One North]] (Level 8)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And you also need some code to read the file and run a regular expression over it:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;import scala.io.Source&lt;br /&gt;object Club &lt;br /&gt;{&lt;br /&gt; def load(filename: String): Iterator[Club] =&lt;br /&gt; {&lt;br /&gt;  // Helper to remove the crud from team names:&lt;br /&gt;  def clean(input:String) = input.replaceAll("&amp;amp;","&amp;").&lt;br /&gt;              replaceAll("AFC","").replaceAll("A.F.C.","").&lt;br /&gt;              replaceAll("F.C.","").trim&lt;br /&gt;&lt;br /&gt;  val fileContents = Source.fromFile(filename, "UTF8").mkString&lt;br /&gt;     &lt;br /&gt;  // Regular expression for extracting team name and level. &lt;br /&gt;  val clubInfo = """\|\[\[([^|\]]+).*\(Level (\d+)\)""".r &lt;br /&gt;    &lt;br /&gt;  for(clubInfo(name,level) &lt;- clubInfo findAllIn fileContents)&lt;br /&gt;    yield new Club(clean(name),level.toInt)&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A couple of points here:  reading a file into memory using &lt;code&gt;Source&lt;/code&gt; and &lt;code&gt;mkString&lt;/code&gt; is rather handy compared to what I'd usually do (i.e, using a buffer and a loop, or grabbing a library that has it defined already); creating a regular expression means calling &lt;code&gt;.r()&lt;/code&gt; on a String which is almost as short as having regular expressions as part of the syntax of the language. But I think it's the &lt;code&gt;for&lt;/code&gt; loop that stands out.  The &lt;code&gt;findAllIn&lt;/code&gt; call looks straight-forward enough, but the left hand side of that is cute.  A regular expression in Scala, such as &lt;code&gt;clubInfo&lt;/code&gt;, is also an "extractor" in the language, which for me is probably best explained by example as I don't have a full grip on all the concepts yet:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ scala&lt;br /&gt;Welcome to Scala version 2.7.2.final [...]&lt;br /&gt;Type in expressions to have them evaluated.&lt;br /&gt;Type :help for more information.&lt;br /&gt;&lt;br /&gt;scala&gt; val clubInfo = """\|\[\[([^|\]]+).*\(Level (\d+)\)""".r &lt;br /&gt;clubInfo: scala.util.matching.Regex = \|\[\[([^|\]]+).*\(Level (\d+)\)&lt;br /&gt;&lt;br /&gt;scala&gt; val clubInfo(name,level) = "|[[Aveley F.C.|Aveley]]||[[Isthmian League]] [[Isthmian League Division One North|Division One North]] (Level 8)"&lt;br /&gt;name: String = Aveley F.C.&lt;br /&gt;level: String = 8&lt;br /&gt;&lt;br /&gt;scala&gt; println(name)&lt;br /&gt;Aveley F.C.&lt;br /&gt;&lt;br /&gt;scala&gt; println(level)&lt;br /&gt;8&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Handy? I think so.  Especially when you can use it in a for loop to split out the matches into the two groups.&lt;br /&gt;&lt;br /&gt;Putting it all together (and you can &lt;a href="http://blog.spiralarm.com/richard/2009/01/hull_prob.zip"&gt;download the source files&lt;/a&gt; if you want) we can print out all the clubs that cannot be coloured in:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ scalac Club.scala &lt;br /&gt;$ scala&lt;br /&gt;Welcome to Scala version 2.7.2.final [...]&lt;br /&gt;Type in expressions to have them evaluated.&lt;br /&gt;Type :help for more information.&lt;br /&gt;&lt;br /&gt;scala&gt; val clubs = Club.load("footballclubs.xml")&lt;br /&gt;clubs: Iterator[Club] = non-empty iterator&lt;br /&gt;&lt;br /&gt;scala&gt; for(club &lt;- clubs; if !club.canBeColouredIn)&lt;br /&gt;     | println(club.name)&lt;br /&gt;Hull City&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So there we have it.  It's true: only Hull City can not be coloured in. For now...&lt;br /&gt;&lt;br /&gt;UPDATE: If you prefer just the script version, here it is condensed:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;def clean(input:String) = input.replaceAll("A.F.C.","").trim&lt;br /&gt;&lt;br /&gt;def isGood(name:String) = &lt;br /&gt;   !name.exists( c =&gt; "&amp;ABDOPQRabdegopq".contains(c) )&lt;br /&gt;&lt;br /&gt;val regexp = """\|\[\[([^|\]]+).*Level""".r &lt;br /&gt;&lt;br /&gt;import scala.io.Source&lt;br /&gt;&lt;br /&gt;for( line &lt;- Source.fromFile("footballclubs.xml", "UTF8").getLines; &lt;br /&gt;     regexp(name) &lt;- regexp findAllIn line; &lt;br /&gt;     if isGood(clean(name)) )&lt;br /&gt;  println(name)&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-4620615739801903503?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2009/01/hull-city-problem-in-scala.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-8073046597125507564</guid><pubDate>Wed, 10 Dec 2008 23:11:00 +0000</pubDate><atom:updated>2008-12-11T00:59:32.074Z</atom:updated><title>Augmented Reality at £5 App Xmas Special</title><description>&lt;a href="http://www.flickr.com/photos/d6y/3098834874/" title="At £5 app by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3079/3098834874_d8793465e3.jpg" width="500" height="375" alt="At £5 app" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There's something right about &lt;a href="http://fivepoundapp.com/"&gt;£5 App&lt;/a&gt; running a demo/game/fun &lt;a href="http://upcoming.yahoo.com/event/1366104/"&gt;event&lt;/a&gt; as the &lt;a href="http://ianozsvald.com/2008/12/01/5-app-xmas-special-listing-details/"&gt;Xmas special&lt;/a&gt;.   I mean, how does this sound: I turn up at &lt;a href="http://thewerks.org.uk/"&gt;The Werks&lt;/a&gt;, icy cold, to be handed a lovely hot mulled wine by the &lt;a href="http://ribot.co.uk/"&gt;Ribot&lt;/a&gt;s, directed towards the mince pies, and then entertained with a range of funky technology stuff. Mmm.&lt;br /&gt;&lt;br /&gt;This evening there were talks and demos covering: collaborative interactive fiction (a.k.a., group-generated text adventure), namely &lt;a href="http://barrymars.co.uk/spaceship/"&gt;Spaceship&lt;/a&gt;; &lt;a href="http://robochick.co.uk/"&gt;Emily&lt;/a&gt; demoing robot sumo; mobile phone &lt;a href="http://lastminutelabs.wordpress.com/projects/"&gt;Lightsaber dueling&lt;/a&gt; (no, not with the iPhone); eye controlled Pong, from &lt;a href="http://www.cogapp.com/home/ben-rubinstein.html"&gt;Ben Rubinstein&lt;/a&gt;. All excellent.  &lt;br /&gt;&lt;br /&gt;Maybe it's because of the fun we had the previous day at the Flash &lt;a href="http://upcoming.yahoo.com/event/1367599/"&gt;Big Screen Bonanza&lt;/a&gt;, or perhaps it's because I'd been noodling with &lt;a href="http://www.javafx.com"&gt;JavaFX&lt;/a&gt;, but I found &lt;a href="http://www.sebleedelisle.com/"&gt;Seb&lt;/a&gt;'s Flash 3D and augmented reality demos great fun.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/d6y/3099087558/" title="Seb augmented reality by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3234/3099087558_77f843b130.jpg" width="500" height="375" alt="Seb augmented reality" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'd say, of the evening, the biggest wow! was when Seb showed us the &lt;a href="http://www.boffswana.com/news/?p=392"&gt;augmented reality stuff&lt;/a&gt;; and the biggest round of applause of the night was when he said "hey, all I've done is download it and compile it" :-)  &lt;br /&gt;&lt;br /&gt;But you don't even need to do that.  From that last link, if you print out &lt;a href="http://www.boffswana.com/news/wp-content/uploads/printme.pdf"&gt;the PDF symbol&lt;/a&gt;, click the start button (and right click and select "USB camera" in settings, but you may not have to do that), and hold up the symbol you can try it yourself.  It's not bad, eh?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/d6y/3098411583/" title="Papervision Augmented Reality by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3177/3098411583_f73b3763df.jpg" width="500" height="357" alt="Papervision Augmented Reality" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The underlying tech seems to be from the C &lt;a href="http://www.hitl.washington.edu/artoolkit/"&gt;ARToolKit&lt;/a&gt;, which is available under &lt;a href="http://www.hitl.washington.edu/artoolkit/license.html"&gt;the GPL and  other licenses&lt;/a&gt;. Given that the documentation touches on support for SGI/Irix and VRML I think it must have a pretty robust &lt;a href="http://www.hitl.washington.edu/artoolkit/documentation/history.htm"&gt;history&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;There's some mention of a Java bindings for it, but after a bit of digging it turns out there's a &lt;a href="http://nyatla.jp/nyartoolkit/wiki/index.php?NyARToolkit%20for%20Java.en"&gt;pure Java 6 port&lt;/a&gt;, and from what I can understand a version from the same author for the Android platform.   I've not tried them; I've no idea if they work.  &lt;br /&gt;&lt;br /&gt;If you're interested in this area, there's documentation on &lt;a href="http://www.hitl.washington.edu/artoolkit/documentation/userarwork.htm"&gt;how ARToolKit works&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-8073046597125507564?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/12/augmented-reality-at-5-app-xmas-special.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-8121034361563447253</guid><pubDate>Thu, 13 Nov 2008 12:52:00 +0000</pubDate><atom:updated>2008-11-13T16:03:05.932Z</atom:updated><title>Brighton Scala User Group</title><description>&lt;a href="http://www.flickr.com/photos/tags/brightonscalausergroup/" title="I left the cover in the pub by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3001/3026491489_4c13130f00.jpg" width="375" height="500" alt="I left the book cover in the pub" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Last night was the Brighton Scala User Group pub &lt;a href="http://upcoming.yahoo.com/event/1263871/"&gt;meet up&lt;/a&gt;.  For the record the conversation covered:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Scala Plugin for Eclipse, how it runs on the Mac, how it lives with Maven.&lt;/li&gt;&lt;li&gt;The power of &lt;a href="http://www.eclipse.org/equinox/incubator/aspects/"&gt;Aspect Orientated Programming&lt;/a&gt; for fixing other people's code.&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/New_I/O"&gt;NIO&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;The JVM language summit, and &lt;a href="http://www.flickr.com/photos/montpelier/sets/72157607759681468/"&gt;photos taken&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Neil Gafter, Closures In Java, what we think NG thinks of Scala.&lt;/li&gt;&lt;li&gt;Refinements, a.k.a. duck typing (see section 3.2.7 and specifically example 3.2.4 on page 22 of the &lt;a href="http://www.scala-lang.org/node/198"&gt;Language Spec&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;Invoke dynamic, tail recursion, catching multiple exceptions.&lt;/li&gt;&lt;li&gt;Is there a JSR for Java 7?&lt;/li&gt;&lt;li&gt;Java 7, do we care about Java language features now?  We do care about the JVM.&lt;/li&gt;&lt;li&gt;Languages on the JVM with parity performance with Java: Scala, Clojure.&lt;/li&gt;&lt;li&gt;Idioms.&lt;/li&gt;&lt;li&gt;Mac keyboards as a way for Apple to lock in users.&lt;/li&gt;&lt;li&gt;What Scala language features Java developers like.&lt;/li&gt;&lt;li&gt;Using existing web frameworks other than Lift with Scala.&lt;/li&gt;&lt;li&gt;Focal length, depth of field.&lt;/li&gt;&lt;li&gt;Sun's war chest.&lt;/li&gt;&lt;li&gt;The Groovy/Grails/Spring Source deal.&lt;/li&gt;&lt;li&gt;Return early v. one and only one return.&lt;/li&gt;&lt;li&gt;Language features for nicely dealing with instanceOf tests.&lt;/li&gt;&lt;li&gt;Interesting corner-cases of the type system.&lt;/li&gt;&lt;li&gt;What *is* it about Scala that's so attractive? What problems is Scala solving?&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://upcoming.yahoo.com/event/1348516/"&gt;next event&lt;/a&gt; will be 17 December 2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-8121034361563447253?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/11/brighton-scala-user-group.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-7039555983314748968</guid><pubDate>Mon, 13 Oct 2008 13:10:00 +0000</pubDate><atom:updated>2008-10-13T14:25:47.533+01:00</atom:updated><title>FOWA 2008 London</title><description>&lt;a href="http://www.flickr.com/photos/d6y/2926818258/" title="Mark Biddulph by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3142/2926818258_2b4068f379.jpg" width="375" height="500" alt="Mark Biddulph" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This year the &lt;a href="http://london2008.futureofwebapps.com/schedule"&gt;London Future of Web Apps conference&lt;/a&gt; was held at the &lt;a href="http://www.excel-london.co.uk/"&gt;ExCel centre&lt;/a&gt;. Ah, the ExCel: a place that feels both sterile and grimy&amp;#8212;something I thought only possible at airports and large shopping centres.&lt;br /&gt;&lt;br /&gt;The conference? It lacked substance, and was disappointing in that respect.  Still, that's not what it's all about: it's good to just take some time away from the keyboard, and talk to people about "stuff".&lt;br /&gt;&lt;br /&gt;I did enjoy...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://hackdiary.com/"&gt;Matt Biddulph&lt;/a&gt; talking about "Dopplr: It's made of messages". A good reminder that scale out is a lot easier if from day one you plan for &lt;a href="http://bitworking.org/news/218/N-1"&gt;N &amp;gt; 1&lt;/a&gt;. I.e,. more than one web server, more than one database, etc.  I was interested to see that Dopplr use &lt;a href="http://activemq.apache.org/"&gt;ActiveMQ&lt;/a&gt; for messaging; and we were pointed at &lt;a href="http://www.eaipatterns.com/index.html"&gt;Enterprise Integration Patterns&lt;/a&gt; as a book worth reading. &lt;/li&gt;&lt;li&gt;Blaine Cook &amp;amp; Joe Stump on "Languages don't scale". A nice set up by insulting pretty much all programming languages, and then saying that of course, it's not about the language, it's about I/O and the architecture of scalability.&lt;/li&gt;&lt;li&gt;Blaine Cook's second presentation was on "Using Jabber to make awesome web sites".  In essence: polling sucks, use PubSub instead, and in particular use the Jabber protocols to make things scale.  Well, &lt;a href="http://roy.gbiv.com/untangled/2008/economies-of-scale"&gt;it doesn't solve all the problems&lt;/a&gt;, but I think the audience by now had taken the hint that messaging is useful.&lt;/li&gt;&lt;li&gt;I enjoyed the TechCrunch Pitch! event, in which five start ups pitched their ideas, Dragon's Den style. Except without any money being involved.  And related to that (in my mind) on the following day was "Work/life balance or Blood, sweat and tears: Which is the startup way?".  This was &lt;a href="http://www.tomnixon.co.uk/"&gt;Tom Nixon&lt;/a&gt; arguing for some sense of work/life balance, while '80s throwback &lt;a href="http://calacanis.com/"&gt;Jason Calacanis&lt;/a&gt; gave the other side of the argument.  He didn't actually use the phrase "greed is good", but it was in the air.   I liked that session; it was strangely energizing.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Those were the highlights for me. You can &lt;a href="http://events.carsonified.com/fowa/2008/london/content"&gt;watch the presentations online&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-7039555983314748968?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/10/fowa-2008-london.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-5590672376646671776</guid><pubDate>Tue, 30 Sep 2008 12:46:00 +0000</pubDate><atom:updated>2008-10-01T05:43:34.704+01:00</atom:updated><title>Tracking down threading issues</title><description>One of the projects we've been working on involves kicking off a number of threads to check on availability of certain services.  Despite having read the fantastic &lt;a href="http://www.javaconcurrencyinpractice.com/"&gt;Java Concurrency in Practice&lt;/a&gt; book (which you should buy, possibly &lt;a href="https://www.amazon.co.uk/dp/0321349601?tag=richarddallaway&amp;camp=1406&amp;creative=6394&amp;linkCode=as1&amp;creativeASIN=0321349601&amp;adid=1WQS7WWCW5S75PR2MJNY"&gt;from Amazon UK&lt;/a&gt;) we'd run into a situation where Tomcat wasn't shutting down.  Inevitably it'd be because we'd starting a thread that wasn't stopping.  As a reminder to myself here are a bunch of useful tools for figuring out what might be going on....&lt;br /&gt;&lt;br /&gt;Step 1: find out what's running with &lt;code&gt;jps -lm&lt;/code&gt;:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ jps -lm&lt;br /&gt;1001 org.apache.catalina.startup.Bootstrap start&lt;br /&gt;1302 sun.tools.jps.Jps -lm&lt;br /&gt;1066 com.j_spaces.core.client.SpaceFinder /./taykt&lt;br /&gt;176 &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This is a list of the Java process IDs which are "typically, but not necessarily, the operating system's process identifier for the JVM process", according to the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html"&gt;JPS manual page&lt;/a&gt;.  In my case, they were the OS process IDs, although I should point out that I'm running this on Mac OS 10.5 using JDK 5, and the tools do vary by operating system.&lt;br /&gt;&lt;br /&gt;What the list is showing me is that the Tomcat process is still running (process 1001).  All the other processes I expect to see on my machine, including the mysterious 176 which happens to be IntelliJ.&lt;br /&gt;&lt;br /&gt;Step 2: take a look at what threads are running in the process, as described in the &lt;a href="http://java.sun.com/j2se/1.5/pdf/jdk50_ts_guide.pdf"&gt;J2SE 5.0 Trouble-Shooting and Diagnostic Guide PDF&lt;/a&gt;:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ kill -QUIT 1001 &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Hmm. No output from that command... of course, because I've signalled to the Tomcat process to give me a thread dump the output will be in the Tomcat logs:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;==&gt; catalina.out &lt;==&lt;br /&gt;Full thread dump Java HotSpot(TM) Client VM (1.5.0_16-133 &lt;br /&gt;mixed mode, sharing):&lt;br /&gt;&lt;br /&gt;"DestroyJavaVM" prio=5 tid=0x010017f0 nid=0xb0801000 waiting &lt;br /&gt; on condition [0x00000000..0xb0800060]&lt;br /&gt;&lt;br /&gt;"SelfCleaningTable$Cleaner" daemon prio=5 tid=0x01049030 &lt;br /&gt; nid=0x8e7a00 in Object.wait() [0xb171f000..0xb171fd90]&lt;br /&gt; at java.lang.Object.wait(Native Method)&lt;br /&gt; - waiting on &lt;0x25f696f8&gt; (a java.lang.ref.ReferenceQueue$Lock)&lt;br /&gt; at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:120)&lt;br /&gt; - locked &lt;0x25f696f8&gt; (a java.lang.ref.ReferenceQueue$Lock)&lt;br /&gt; at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:136)&lt;br /&gt; at com.j_spaces.obf.eb.run(SourceFile:231)&lt;br /&gt;&lt;br /&gt;"pool-1-thread-1" prio=5 tid=0x01021470 nid=0x8f0c00 waiting&lt;br /&gt;  on condition [0xb0c8a000..0xb0c8ad90]&lt;br /&gt; at sun.misc.Unsafe.park(Native Method)&lt;br /&gt; at java.util.concurrent.locks.LockSupport&lt;br /&gt;   .park(LockSupport.java:118)&lt;br /&gt; at java.util.concurrent.locks.AbstractQueuedSynchronizer$&lt;br /&gt;   ConditionObject.await(AbstractQueuedSynchronizer.java:1841)&lt;br /&gt; at java.util.concurrent.LinkedBlockingQueue&lt;br /&gt;   .take(LinkedBlockingQueue.java:359)&lt;br /&gt; at java.util.concurrent.ThreadPoolExecutor&lt;br /&gt;   .getTask(ThreadPoolExecutor.java:470)&lt;br /&gt; at java.util.concurrent.ThreadPoolExecutor$Worker&lt;br /&gt;   .run(ThreadPoolExecutor.java:674)&lt;br /&gt; at java.lang.Thread.run(Thread.java:613)&lt;br /&gt;...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;...it goes on for a bit.  The parts I was interested in were non-daemon processes (because daemon ones are shutdown when the JVM shutsdown).  In my case, the "pool-1-thread-1" process reminded me that we'd put a few things into an &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executor.html"&gt;Executor&lt;/a&gt; and possibly not cleaned up properly.  I know it was that thread name, because I'd seen it in the application log files.   A quick dip into Java Concurrency in Practice to remind myself about The Rules, and I had a few modifications that resolved the issue. But...&lt;br /&gt;&lt;br /&gt;Step 3: try out &lt;a href="http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html"&gt;JConsole&lt;/a&gt;.   The trick here is that you need to set a flag at Tomcat start up time:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ export CATALINA_OPTS="-Dcom.sun.management.jmxremote"&lt;br /&gt;$ sh startup.sh&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Then a quick &lt;code&gt;jps -lm&lt;/code&gt; to find the process number, then fire up JConsole with &lt;code&gt;jconsole &lt;i&gt;pid goes here&lt;/i&gt;&lt;/code&gt; and you're set.  Not only do you get easier access to the thread list, you also have buttons in the MBean tab with tempting names.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-5590672376646671776?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/09/tracking-down-threading-issues.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-4719601094706038808</guid><pubDate>Tue, 05 Aug 2008 11:58:00 +0000</pubDate><atom:updated>2008-08-06T23:06:13.522+01:00</atom:updated><title>GGUG Meeting</title><description>I have a love/hate relationship with &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;. I do find it wonderfully productive for hammering out a quick script to do something, but I feel uneasy attempting anything larger without my crutches of static analysis (strict shouty compilers and &lt;a href="http://findbugs.sourceforge.net/"&gt;Find Bugs&lt;/a&gt;) and knowing there are great profilers if I need them.   Yet, when returning to Java I'm left thinking "why do I have to write so much code?".&lt;br /&gt;&lt;br /&gt;You'll understand, then, why I find Scala so appealing. &lt;br /&gt;&lt;br /&gt;Still, I do use Groovy, and mostly I use Groovy in the context of &lt;a href="http://grails.org/Home"&gt;Grails&lt;/a&gt;, where I enter small snippets of Groovy to get the job done.   Even here, though, I rely on an IDE to help and the only really usable one is IntelliJ where they have done a great job on supporting Grails.  Having said that, the &lt;a href="http://hansamann.podspot.de/"&gt;Grails Podcast&lt;/a&gt; have mentioned that there's been some good Grails work in Netbeans 6.5.  Don't get me wrong: Netbeans is a great tool, but in some respects it always seems to be "jam tomorrow"....&lt;br /&gt;&lt;br /&gt;To keep up-to-date with the Grails world, I headed up to the &lt;a href="http://skillsmatter.com/"&gt;Skillsmatter&lt;/a&gt; for the &lt;a href="http://upcoming.yahoo.com/event/923449/"&gt;Groovy and Grails User Group Meeting&lt;/a&gt;.  It was good to see who's using Grails and how people are using Grails, to chat with them at the pub, but also it was handy to hear &lt;a href="http://graemerocher.blogspot.com/"&gt;Graeme Rocher&lt;/a&gt; give a "state of grails" talk. And there's some great stuff in the pipeline for 1.1:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;plugins are going to be installed once on your machine and only the meta data will be written to your project, and the plugin system will resolve dependencies for you;&lt;/li&gt;&lt;li&gt;the plugin system is going to be faster at finding and listing plugins;&lt;/li&gt;&lt;li&gt;plugins can be scoped (e.g., this plugin just for testing, not deployment);&lt;/li&gt;&lt;li&gt;improved Maven support (the Grails POMs have been published already, I believe);&lt;/li&gt;&lt;li&gt;decoupling of components out of Grails, including GORM and GSP;&lt;/li&gt;&lt;li&gt;better Java integration, such as for JPA, JSP, portlets; and&lt;/li&gt;&lt;li&gt;OSGi support after 1.1.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;And I suspect there will be hundreds of smaller changes too.  All this is schedule for Dec 08/ Jan 09, which is the same timeframe as the two new Grails books: &lt;a href="http://www.manning.com/gsmith/"&gt;Grails in Action&lt;/a&gt; and the 2nd edition of &lt;a href="http://www.apress.com/book/view/1590597583"&gt;The Definitive Guide to Grails&lt;/a&gt; (I would not recommend buying the 1st edition now, as it was based on Grails 0.3).  As I'm mentioning books I'll just say that I found &lt;a href="http://www.pragprog.com/titles/vslg/programming-groovy"&gt;Programming Groovy: Dynamic Productivity for the Java Developer&lt;/a&gt; to be pretty useful.&lt;br /&gt;&lt;br /&gt;The event was recorded, and it looks like it will appear on the &lt;a href="http://skillsmatter.com/podcast/java-jee/grails"&gt;Skillsmatter Java podcast page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-4719601094706038808?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/08/ggug-meeting.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-6651171266646417314</guid><pubDate>Wed, 23 Jul 2008 06:06:00 +0000</pubDate><atom:updated>2008-07-23T09:52:26.046+01:00</atom:updated><title>Scala London Coding Dojo</title><description>&lt;a href="http://www.flickr.com/photos/d6y/2689665763/" title="Gareth is at the keyboard by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3199/2689665763_276ff4ce28.jpg" width="500" height="375" alt="Gareth is at the keyboard" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://upcoming.yahoo.com/event/812966/"&gt;Monday&lt;/a&gt; was the first &lt;a href="http://www.nabble.com/-scala--LSUG-ThoughtWorks-Code-Dojo-on-21-July-p18112754.html"&gt;Scala London User Group meeting&lt;/a&gt; that was held around a keyboard. &lt;a href="http://www.linkedin.com/pub/2/100/4aa"&gt;Robert Rees&lt;/a&gt; arranged for a room, food, and drink at &lt;a href="http://www.thoughtworks.com/"&gt;ThoughtWorks&lt;/a&gt;, &lt;a href="http://sygneca.com/"&gt;Jamie Webb&lt;/a&gt; kindly gave an intro to Scala talk, and Aaron Roth provided print outs of a &lt;a href="http://blogs.sun.com/sundararajan/entry/scala_for_java_programmers"&gt;Scala for Java Programmers cheat sheet&lt;/a&gt;...and so we spent time working on the &lt;a href="http://codekata.pragprog.com/2007/01/code_kata_one_s.html"&gt;supermarket problem&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I counted 19 people (of which 3 were Brighton based), of mixed abilty (from functional people or Java people who had never touched Scala, all the way to expert Scala-heads), and we had working, unit tested, software by 10pm. Which—given that coding dojos &lt;a href="http://www.codingdojo.org/cgi-bin/wiki.pl?WhatIsCodingDojo"&gt;sound a bit mad&lt;/a&gt;—is pretty good going.&lt;br /&gt;&lt;br /&gt;Dojos are probably not going to be the way forward for this group, but I think it did a good job as an ice-breaker: an inclusive activity; a task that's not daunting, that anyone can have a crack at. I definitely learnt stuff: testing using &lt;a href="http://code.google.com/p/specs/"&gt;Specs&lt;/a&gt;, and need to understand the Scala patterns, such as &lt;a href="http://scala.sygneca.com/patterns/component-mixins"&gt;Cake&lt;/a&gt; for dependency injection, and I have to stop putting off looking at &lt;a href="http://liftweb.net/"&gt;Lift&lt;/a&gt;. Perhaps the most important thing for me was to learn that the Eclipse Scala plugin is going to be able to do mixed compilation of Java and Scala source in a project.&lt;br /&gt;&lt;br /&gt;There was video of Jamies talk. I'll add a link if it's posted any place. At the moment there's no web site for lsug but &lt;a href="http://www.spiralarm.com/view/contactUs"&gt;get in touch&lt;/a&gt; if you'd like the mailing list email address.&lt;br /&gt;&lt;br /&gt;There are more &lt;a href="http://www.flickr.com/photos/tags/lsug/"&gt;photos on Flickr tagged with lsug.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-6651171266646417314?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/07/scala-london-coding-dojo.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-3391925623791450728</guid><pubDate>Sat, 14 Jun 2008 10:09:00 +0000</pubDate><atom:updated>2008-07-23T09:59:03.540+01:00</atom:updated><title>Comparing closures in Java, Groovy and Scala</title><description>On &lt;a href="http://www.goulbourn.com"&gt;Paul&lt;/a&gt;'s return from JavaOne this year, we spoke about &lt;a href="http://gafter.blogspot.com/"&gt;Neal Gafter&lt;/a&gt;'s Closures Cookbook talk.  From what I understood, this was a look at the &lt;a href="http://www.javac.info/"&gt;BGGA closures proposal&lt;/a&gt;, and contained an example that pushed hard on some of the tougher closure issues for Java.  I thought it might be fun to look at the Java example from the talk, and covert it to &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; and &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Why those languages?  Because they are the three &lt;a href="http://en.wikipedia.org/wiki/Java_Virtual_Machine"&gt;JVM&lt;/a&gt; languages I'm most interested in.  I suppose I could also have compared the closure support in &lt;a href="http://www.jython.org/Project/"&gt;Jython&lt;/a&gt;, &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; or... well, there are &lt;a href="http://en.wikipedia.org/wiki/JVM_Languages"&gt;a few to choose from&lt;/a&gt;, but this blog is going to be plenty long enough with just three. &lt;br /&gt;&lt;br /&gt;Let's start with the Java example that was given, remembering that this is a proposed syntax, that may or may not make it to Java 7 or later.  As I understood the example it was this: imagine you want to add the ability to time a block of code, and you wanted to do it in a way that would look almost like a new keyword has been added to the language; and you wanted to pass in a parameter to name what you were timing; and the block you're timing returns a result, or might throw an exception.  So, quite an involved case.  &lt;br /&gt;&lt;br /&gt;Here's how the current Java proposal looks:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;// Here's a method that uses the time call:&lt;br /&gt;int f() throws MyException { &lt;br /&gt;  time("opName", {=&gt; &lt;br /&gt;    // some statements that can throw MyException &lt;br /&gt;  }); &lt;br /&gt;  time("opName", {=&gt; &lt;br /&gt;    return ...compute result...; &lt;br /&gt;  }); &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So we're timing a couple of operations, and we're doing this inside a method, &lt;code&gt;f&lt;/code&gt;, that returns an integer.  The implementation would be....&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;interface Block&lt;R, throws X&gt; { &lt;br /&gt;  R execute() throws X; &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;public &lt;R, throws X&gt; R time( &lt;br /&gt;    String opName, Block&lt;R, X&gt; block) throws X { &lt;br /&gt;  long startTime = System.nanoTime(); &lt;br /&gt;  boolean success = true; &lt;br /&gt;  try { &lt;br /&gt;    return block.execute(); &lt;br /&gt;  } catch (final Throwable ex) { &lt;br /&gt;    success = false; &lt;br /&gt;    throw ex; &lt;br /&gt;  } finally { &lt;br /&gt;    recordTiming( &lt;br /&gt;      "opName", System.nanoTime() - startTime, success); &lt;br /&gt;  } &lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;As you can see, &lt;code&gt;time&lt;/code&gt; takes an arbitrary text label and a block of code, runs the block and tells you how long the block took to run and if it succeeded or not. &lt;br /&gt;&lt;br /&gt;That's the example that was given at JavaOne.  Now for the same thing in Groovy...&lt;br /&gt;&lt;br /&gt;To make runnable code for Groovy (and for Scala), I had to decided to time something.  So I'm timing a block of code that randomly throws an exception or returns something.  And then timing a block of code that just returns a number.  In Groovy that would be:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;def time(opname, block)&lt;br /&gt;{ &lt;br /&gt; long start_time = System.nanoTime()&lt;br /&gt; boolean success = true&lt;br /&gt; try {&lt;br /&gt;  return block()&lt;br /&gt; } catch (Throwable ex) {&lt;br /&gt;  success = false;&lt;br /&gt;  throw ex&lt;br /&gt; } finally {&lt;br /&gt;  diff = System.nanoTime() - start_time&lt;br /&gt;  println "$opname $diff $success"&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int f() throws Exception {&lt;br /&gt; time("a") { &lt;br /&gt;  Random r = new Random()&lt;br /&gt;  if (r.nextInt(100) &gt; 50)&lt;br /&gt;   throw new IOException("Boom")&lt;br /&gt;  else&lt;br /&gt;   return 42&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt; time("b") {&lt;br /&gt;  return 7&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;println f()&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;An example of running the code:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;$ groovy time.groovy &lt;br /&gt;a 37116000 true&lt;br /&gt;b 69000 true&lt;br /&gt;7&lt;br /&gt;&lt;br /&gt;$ groovy time.groovy &lt;br /&gt;a 39998000 false&lt;br /&gt;Caught: java.io.IOException: Boom&lt;br /&gt; at time$_f_closure1.doCall(time.groovy:21)&lt;br /&gt; at time$_f_closure1.doCall(time.groovy)&lt;br /&gt; at time.time(time.groovy:6)&lt;br /&gt; at time.f(time.groovy:18)&lt;br /&gt; at time.run(time.groovy:31)&lt;br /&gt; at time.main(time.groovy)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Note that the Java example is typed in that it uses a generic type, &lt;code&gt;R&lt;/code&gt;, for the return value which gives you some compile-time checks. That is, when you run &lt;code&gt;time&lt;/code&gt; and use the result, the compiler will enforce that your declaration of the result has the same type as the return type of the block you're timing.  &lt;br /&gt;&lt;br /&gt;Although &lt;a href="http://groovy.codehaus.org/Generics"&gt;Groovy does support generics&lt;/a&gt;, I've not used them here, and as a result the Groovy example doesn't have that type-safety.  I think that's the way one would typically write Groovy code.&lt;br /&gt;&lt;br /&gt;UPDATE: as was pointed out to me in the comments on the &lt;a href="http://java.dzone.com/articles/comparing-closures-java-groovy"&gt;Java Lobby version of this blog post&lt;/a&gt;, this isn't the same as the Java version.  In the Java version a &lt;code&gt;return&lt;/code&gt; in the closure returns out of the enclosing block.&lt;br /&gt;&lt;br /&gt;Now a look at the same code in Scala:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;def time[R](opname: String)(block: =&gt; R) = {&lt;br /&gt; val start_time = System.nanoTime()&lt;br /&gt; var success = true&lt;br /&gt; try {&lt;br /&gt;  block&lt;br /&gt; } catch {&lt;br /&gt;  case ex: Throwable =&gt; {&lt;br /&gt;   success = false;&lt;br /&gt;   throw ex&lt;br /&gt;   }&lt;br /&gt; } finally {&lt;br /&gt;  val diff = System.nanoTime() - start_time&lt;br /&gt;  println(opname + " " + diff + " "+success)&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def f():Integer = {&lt;br /&gt;&lt;br /&gt; val answer = time("a") {&lt;br /&gt;  val r = new Random()&lt;br /&gt;  if (r.nextInt(100) &gt; 50)&lt;br /&gt;   throw new java.io.IOException("Boom")&lt;br /&gt;  else&lt;br /&gt;       "42" &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; println ("the answer, "+answer+" is of type "+&lt;br /&gt;      answer.getClass())&lt;br /&gt;&lt;br /&gt; val seven:Integer = time("b") {&lt;br /&gt;  7&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; println ("seven is of type "+seven.getClass())&lt;br /&gt; &lt;br /&gt; return seven &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;f()&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I'm still not using Scala day-to-day, so this might be a little awkward: thank you to the London Scala User Group for helping me clean up my syntax, but all the mistakes are mine.  &lt;br /&gt;&lt;br /&gt;This code has the same properties as the Java code (type safety via the &lt;code&gt;R&lt;/code&gt; generic type), but seems a little shorter and neater.  Additionally, the thing I like about the Scala code (and the Groovy code) is that the languages return the value of the last statement in a block, and that the syntax allows a clean &lt;code&gt;time("thing") { ... }&lt;/code&gt; format.&lt;br /&gt;&lt;br /&gt;One observation: I've used the &lt;code&gt;Integer&lt;/code&gt; class, which is deprecated, in order to be able to print out the class of the return type in the function &lt;code&gt;f()&lt;/code&gt;.  Without the &lt;code&gt;:Integer&lt;/code&gt; declaration I was getting weird compile errors.  As I said, my understanding of Scala and type inference isn't there yet.&lt;br /&gt;&lt;br /&gt;The output from running the code:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;a 913000 true&lt;br /&gt;the answer, 42 is of type class java.lang.String&lt;br /&gt;b 13000 true&lt;br /&gt;seven is of type class java.lang.Integer&lt;br /&gt;&lt;br /&gt;a 936000 false&lt;br /&gt;java.io.IOException: Boom&lt;br /&gt; at Main$$anonfun$1.apply((virtual file):26)&lt;br /&gt; at Main$$anonfun$1.apply((virtual file):23)&lt;br /&gt; at Main$.time$1((virtual file):8)&lt;br /&gt; at Main$.f$1((virtual file):23)&lt;br /&gt; at Main$.main((virtual file):44)&lt;br /&gt; at Main.main((virtual file))&lt;br /&gt;// rest of stack trace removed&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;There's no conclusions here.  It's just an exercise in comparing closures code in three different languages.  I've probably missed some of the nuances of the Java example, but hey... it's a starting point.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-3391925623791450728?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/06/comparing-closures-in-java-groovy-and.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-5653980799438730368</guid><pubDate>Tue, 13 May 2008 08:34:00 +0000</pubDate><atom:updated>2008-05-13T13:25:26.805+01:00</atom:updated><title>Mobile Monday: Monetisation through Advertising</title><description>&lt;a href="http://www.flickr.com/photos/d6y/2489464226/" title="Mobile Monday by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3274/2489464226_6c8688fa34_m.jpg" width="240" height="164" alt="Mobile Monday" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Last night I was at &lt;a href="http://mobilemonday.org.uk/"&gt;Mobile Monday London&lt;/a&gt; to catch four presentations.  The topic: advertising on mobile. The summary: there's a need for better measurement.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.linkedin.com/pub/3/820/896"&gt;Claire Valoti&lt;/a&gt; from Mindshare was up first, giving the agency view of mobile advertising.  She split the appeal of mobile in a media plan in to two parts: as a delivery mechanic (to extended reach, getting to a winder audience in a different mode); and as a platform (for couponing, or video uploads).  She then went on to describe some issues and themes... and standardization and measurement were pretty much top of the list.  That is, there's currently no good standard measure of reach, sessions, traffic or users for mobile advertising.  And even if there was, it needs to be integrated into existing web buying systems, rather than via a mobile-specific system. &lt;br /&gt;&lt;br /&gt;Claire had a good observation on social networking, and the importance for mobile.  The m:metrics numbers quoted showed that the 18-24 and 25-34 age groups were more likely to be using social networking from the mobile, compared to 13-17 age group.  It's not just about a youth market.&lt;br /&gt;&lt;br /&gt;Another good point was made that events drive handset usage, as does "the right handset".  An example given: at the end of the football (soccer) season, there's a drop in usage; during the season people are out and about and will use the mobile internet to look up news.   As for "the right device", just look at &lt;a href="http://arstechnica.com/journals/apple.ars/2008/03/18/iphone-crushes-competition-in-smartphone-usage"&gt;the figures&lt;/a&gt; for internet usage on the iPhone compared to anything else....&lt;br /&gt;&lt;br /&gt;Obviously mobile advertising has to be used in the context of the whole campaign, and it has to be relevant content: don't go taking an ad made for TV and slapping it on a mobile.   Use the right techniques to get reach (banners, SMS, bluetooth), use location information to make it relevant, use coupons and free content to make it useful to the customer.  And the user experience needs to be more streamlined: don't issue mobile coupons without telling your retail staff how to handle them.&lt;br /&gt;&lt;br /&gt;Aside from measurement, another barrier to growing advertising budgets is the number of people involved in setting up a mobile campaign.  The buying experience needs to be more streamlined.&lt;br /&gt;&lt;br /&gt;Mobile advertising challenges were summarized as: speed, reach, cost, ROI, standards, and measurement.  As examples of reach issues: Claire was interested in QR codes, but only 10% of mobile devices have a reader installed;   buying from Blyk or similar to get an audience was described as having "limited reach" at the moment;  mobile search  needs to scale up as, right now, it's hard to spend the budget.&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.linkedin.com/pub/1/5b4/a7a"&gt;Shan Henderson&lt;/a&gt; from Vodafone kicked off his presentation by saying that it's the metrics that matter.  Click rate is not the full story, but it's often the headline.  Also audience demographic, behaviour, session length, frequency and reach are all important because "money follows measurement in media".  He showed the "measurement gap" graph.  I'm sure the slides will be available soon, but for now I've done a shaky recreation:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/d6y/2489490412/" title="measurement gap by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3090/2489490412_6a26c07bd5.jpg" width="500" height="375" alt="measurement gap" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(I'm guessing &lt;a href="http://www.edwardtufte.com/tufte/"&gt;Edward Tufte&lt;/a&gt; would not approve).  So, we all agree it seems: we need better standards for measurement and more efficency in the buying and selling of advertising in order for the market to grow.&lt;br /&gt;&lt;br /&gt;To address this, Shan went on to describe the &lt;a href="http://www.gsmworld.com/news/press_2008/press08_11.shtml"&gt;GSMA Metrics Study&lt;/a&gt; which aims to make it easy to plan and measure mobile media. Later this year it's going to produce (one or more of): guidelines, best practices, definitions, technical standards, responsible ad practices, content standards. This will all be via an as yet unnamed ABC-like trusted independent organization.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.linkedin.com/in/russellbuckley"&gt;Russell Buckley&lt;/a&gt; took the stage to talk about Admob, a self-serve and full-service ad network, shifting 2.bn ads a month, in 160 countries via 3000 mobile web sites.  They select mobile sites, put ads on them, and share the revenue with the site.    He described mobile advertising as good for: bands; to promote mobile websites; for operators to monetize their sites; and content owners to have access to a new marketing channel.&lt;br /&gt;&lt;br /&gt;There was then a page of logos of who's advertising, and it showed that the US is generally ahead in terms of adopting mobile advertising.  In fact, ad requests by country (to March) showed 47% of ads were for the USA.  Other figures were: India (9.8%); UK (6.7%); South Africa (5.3%); Indonesia (4.7%); Romania (1.9%); Canada (1.3%); Philippines (1.3%); France (1%); Israel (1%); RoW (20.1%).  By handset, Nokia were the top, although they are dropping: something that's not yet reflected in their market share.&lt;br /&gt;&lt;br /&gt;Russell presented some case studies.  MTV wanted to drive traffic to an awards site, and using text adverts they had a 300% traffic boost and 400% increase in downloads. Land Rover USA saw 23% of users interacting with an advertised landing page, with 3% going on to click the link to make a call to a dealer. Adidas saw a CTR of "well above 3%".  Coca-Cola saw a CTR of 1.31%, but 130% watched a mobile video that was being promoted (some people watched it more than once).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bango.com"&gt;Ray Anderson from Bango&lt;/a&gt; described the basic model for using advertising as: select a channel, measure response, look at user purchases,   analyse ROI, then... repeat.&lt;br /&gt;&lt;br /&gt;He made some great observations on the issues of search.  Depending on the combinations of search provider and operator, you may find you get very different results from the advertising spend (especially if the content is transcoded).  But he had a graph that compared the revenue Bango customers had received over time from Orange and Vodafone: the doubling (or more) in the graphs when the operators introduced a search page was impressive.&lt;br /&gt;&lt;br /&gt;After the talks there was a brief panel session.  All good stuff.  And held in a great building.&lt;br /&gt;&lt;br /&gt;Photos: &lt;a href="http://www.flickr.com/photos/route79/tags/momolondon/"&gt;from Route79&lt;/a&gt;, &lt;a href="http://www.flickr.com/photos/torgo/"&gt;from appelquist&lt;/a&gt;, &lt;a href="http://www.flickr.com/photos/alexcraxton/sets/72157605031653604/"&gt;from Alex Craxton&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Video and audio: usual appear on the &lt;a href="http://mobilemonday.org.uk/"&gt;Mobile Monday web site&lt;/a&gt; after a little while, so check there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-5653980799438730368?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/05/mobile-monday-monetisation-through.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-6332708407287992362</guid><pubDate>Sun, 13 Apr 2008 11:48:00 +0000</pubDate><atom:updated>2008-04-23T19:32:34.492+01:00</atom:updated><title>Decrypting JetS3t Files</title><description>This post is going to be a bit niche.  The scenario is that you've used &lt;a href="http://jets3t.s3.amazonaws.com/index.html"&gt;JetS3t&lt;/a&gt; to backup data to &lt;a href="http://www.amazon.com/gp/browse.html?node=16427261"&gt;Amazon S3&lt;/a&gt; via the &lt;a href="http://jets3t.s3.amazonaws.com/applications/synchronize.html"&gt;synchronize&lt;/a&gt; tool, and in particular you've used the &lt;code&gt;-c&lt;/code&gt; option to encrypt the data.  But you've downloaded the file with another tool, such as &lt;a href="http://www.binarynights.com/"&gt;ForkLift&lt;/a&gt; or &lt;a href="http://people.no-distance.net/ol/software/s3/"&gt;S3 Browser&lt;/a&gt;.  How do you decrypt the downloaded file?&lt;br /&gt;&lt;br /&gt;The default encryption is PBEWithMD5AndDES, and with that knowledge you may be able to find a tool that can decrypt it for you.  I went a different way, and just hooked straight into the encryption utilities inside JetS3t:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;// Apache 2 license &lt;br /&gt;public static void main(final String... args) &lt;br /&gt;    throws GeneralSecurityException, IOException&lt;br /&gt;    {&lt;br /&gt;      &lt;br /&gt;        if (args.length != 4 &amp;&amp; args.length != 2)&lt;br /&gt;        {&lt;br /&gt;            System.err.println(&lt;br /&gt;              "Usage: Decrypt [-alg algorithm] KEY FILE");&lt;br /&gt;            System.exit(1);&lt;br /&gt;        }&lt;br /&gt;   &lt;br /&gt;        final String alg;&lt;br /&gt;        final String key;&lt;br /&gt;        final File encryptedFile;&lt;br /&gt;        &lt;br /&gt;        if (args.length == 4)&lt;br /&gt;        {&lt;br /&gt;            alg = args[1];&lt;br /&gt;            key = args[2];&lt;br /&gt;            encryptedFile = new File(args[3]);&lt;br /&gt;        }&lt;br /&gt;        else // use defaults for algorithm:&lt;br /&gt;        {&lt;br /&gt;            alg = "PBEWithMD5AndDES";&lt;br /&gt;            key = args[0];&lt;br /&gt;            encryptedFile = new File(args[1]);&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        final EncryptionUtil eu = new EncryptionUtil(&lt;br /&gt;                key, alg, EncryptionUtil.DEFAULT_VERSION);&lt;br /&gt;        &lt;br /&gt;        CipherInputStream decrypt=null;&lt;br /&gt;        BufferedOutputStream outStream=null;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            decrypt = eu.decrypt(&lt;br /&gt;                 new FileInputStream(encryptedFile));&lt;br /&gt;            IOUtils.copy(decrypt, System.out);&lt;br /&gt;        }&lt;br /&gt;        finally&lt;br /&gt;        {&lt;br /&gt;            IOUtils.closeQuietly(decrypt);&lt;br /&gt;            IOUtils.closeQuietly(System.out);&lt;br /&gt;        }&lt;br /&gt;               &lt;br /&gt;    }&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So with a bit of fiddling you can copy, paste and compile that (you'll need the JetS3t library and supporting JARs, plus &lt;a href="http://commons.apache.org/io/"&gt;Commons IO&lt;/a&gt;).  Or you can download &lt;a href="http://download.spiralarm.com/blog/richard/2008/04/jets3t-decrypt-dist.zip"&gt;jets3t-decrypt-dist.zip&lt;/a&gt;, which contains the source and the reqired libraries.  Once inside the ZIP you can run:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt; java -jar Jets3tDecrypt.jar password encrypted.file &lt;br /&gt;                 &amp;gt; decrypted.file&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The libraries and the &lt;code&gt;Jets3tDecrypt.jar&lt;/code&gt; was packaged automatically by &lt;a href="http://www.netbeans.org/"&gt;Netbeans 6.1&lt;/a&gt;, which is a lovely touch from an IDE.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-6332708407287992362?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/04/decrypting-jets3t-files.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-5236164491613658880</guid><pubDate>Sun, 16 Mar 2008 16:18:00 +0000</pubDate><atom:updated>2008-03-16T16:47:59.477Z</atom:updated><title>QuickTime for Java</title><description>A few months ago I was experimenting with &lt;a href="http://developer.apple.com/quicktime/qtjava/"&gt;QuickTime for Java&lt;/a&gt;.  It's the binding between Apple's QuickTime "stuff" and the Java language, allowing a Java developer to invoke QuickTime on the Mac (and presumably also on Windows).  The reason this appeals is that we do Java, and have accumulated a fair amount of &lt;a href="http://www.apple.com/xserve/"&gt;Mac hardware&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To cut a long story short, my limited experienced shows that QuickTime, when compared to the standard Java image libraries, produced smaller images of higher quality, faster.  It's unusual to get all three benefits together (smaller, faster, better).  Too good to be true, even, which leads me to think I've screwed up someplace, but I've not spotted it yet.  &lt;br /&gt;&lt;br /&gt;The particular test that interested me was was taking a camera phone photo, resizing it and rotating it.  Here's an example original:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/d6y/1168459141/" title="Jack: Wet dog by d6y, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1305/1168459141_17c8225b74.jpg" width="375" height="500" alt="Jack: Wet dog" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's the rotation using tried-and-trusted &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/geom/AffineTransform.html"&gt;AffineTransform&lt;/a&gt; plus &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/imageio/ImageIO.html"&gt;ImageIO&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/d6y/2337987708/" title="javax.2d Dog by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3054/2337987708_93931dd8fe_o.jpg" width="320" height="240" alt="javax.2d Dog" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And here's the same transformation run through QuickTime for Java using the &lt;code&gt;GraphicsImporter&lt;/code&gt; and &lt;code&gt;Matrix&lt;/code&gt; objects:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/d6y/2337151889/" title="QT4J Dog by d6y, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3157/2337151889_4bb7049166_o.jpg" width="320" height="240" alt="QT4J Dog" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now, it's subtle but the QT4J image looks to have sharper colours, and seems to be a better representation of the original input.  It's also 20k compared to the 76k using the Java 2D libraries, and the code runs 1.7 times faster.  The downside: you need Apple hardware.  &lt;br /&gt;&lt;br /&gt;A few conclusions: it seems the Java 2D code doesn't just fall through to QuickTime on the Apple platform in any simple sense (which, I suppose I might have naively expected).  Second, I suspect there's a lot of tuning that can be done in the Java 2D client usage to improve the quality, but QT4J seems to have good defaults.  &lt;br /&gt;&lt;br /&gt;(Before you ask, the dog's name is Jack.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-5236164491613658880?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/03/quicktime-for-java.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-11993899.post-4884598867884658748</guid><pubDate>Sun, 03 Feb 2008 14:44:00 +0000</pubDate><atom:updated>2008-02-05T18:04:31.404Z</atom:updated><title>Getting Started with Scala</title><description>Friday night was the first London &lt;a href="http://en.wikipedia.org/wiki/Scala_%28programming_language%29"&gt;Scala&lt;/a&gt; User Group meet-up, so it seems like the right time to say what I've learned so far about &lt;a href="http://www.scala-lang.org/"&gt;the language&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm not a functional programming person.  My background, pre-Java and C, was dominated by &lt;a href="http://en.wikipedia.org/wiki/POP-11"&gt;POP-11&lt;/a&gt; so it's fair to say I'm more comfortable with &lt;a href="http://en.wikipedia.org/wiki/Imperative_programming"&gt;imperative coding&lt;/a&gt; than anything else.  But that's kind of why Scala's a serious consideration for me: it doesn't force the functional stuff down your throat, but rather it's all there, object and functional, so you can pick and choose.&lt;br /&gt;&lt;br /&gt;Other compelling aspects of the language are: it runs on the JVM, which has had a huge engineering investment to make it as fast as it is today; has Java-like features, but looks like it lets you get your work done with less lines of code; and it's strongly typed. In other words, it's comfy for a Java person, while putting you in a position to use the funky actors and functional stuff, and maybe make even better use of those multi-core machines. &lt;br /&gt;&lt;br /&gt;Here's an example of less-lines-of-code thing.  In Java, the type-safe idiom for iterating over a map is:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;final Map&amp;lt;String, String&amp;gt; map &lt;br /&gt;    = new HashMap&amp;lt;String, String&amp;gt;();&lt;br /&gt;map.put("dog", "woof");&lt;br /&gt;map.put("cat", "meow");&lt;br /&gt;&lt;br /&gt;for(Map.Entry&amp;lt;String, String&amp;gt; entry : map.entrySet())&lt;br /&gt;{&lt;br /&gt;  final String name = entry.getKey();&lt;br /&gt;  final String value = entry.getValue();&lt;br /&gt;  // do something with name and value here&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The same code, just as strongly typed, in Scala is:&lt;br /&gt;&lt;div class="sourcecode"&gt;&lt;br /&gt;val map = Map[String,String]("dog" -&gt; "woof", "cat" -&gt; "meow")&lt;br /&gt;for( (name,value) &lt;- map)&lt;br /&gt;{&lt;br /&gt; // do something with name and value here&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Or, if you wanted that last part could be: &lt;code&gt;map.foreach( (pair) =&gt; ...do something with pair._1 and pair._2 here.. )&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;If you're interested in getting into this stuff, I found it useful to start with &lt;a href="http://www.scala-lang.org/docu/files/ScalaTutorial.pdf"&gt;A Scala Tutorial for Java programmers PDF&lt;/a&gt;, then listen to &lt;a href="http://www.se-radio.net/podcast/2007-07/episode-62-martin-odersky-scala"&gt;Episode 62 of Software Engineering Radio&lt;/a&gt;, an interview with Martin Odersky on Scala (thanks to &lt;a href="http://happygiraffe.net/blog/"&gt;Dom&lt;/a&gt; for pointing that out to me).&lt;br /&gt;&lt;br /&gt;After that, I think the best place to go is into your wallet and buy a copy of &lt;a href="http://www.artima.com/shop/forsale"&gt;Programming in Scala: A comprehensive step-by-step guide&lt;/a&gt;.  It's a pre-print, with quite a few errors, but I'm pretty sure they'll get cleaned up soon and it'll be a great text.&lt;br /&gt;&lt;br /&gt;Tags: &lt;a rel="tag" href="http://technorati.com/tag/scala"&gt;scala&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;UPDATE: oops, I forgot to escape the &amp;lt; and &amp;gt; tags in the Java example above, which hid the generic types of the map. Fixed now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11993899-4884598867884658748?l=blog.spiralarm.com%2Frichard' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.spiralarm.com/richard/2008/02/getting-started-with-scala.html</link><author>noreply@blogger.com (Richard)</author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></item></channel></rss>