<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2314459346745910857</id><updated>2011-11-27T15:57:13.084-08:00</updated><category term='scala programming'/><category term='scala scalide programming java jvm interpreter ide'/><title type='text'>Scalide</title><subtitle type='html'>&lt;a href="http://code.google.com/p/scalide/"&gt;Scalide Homepage on GoogleCode&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-1993514186709862864</id><published>2010-06-15T18:51:00.000-07:00</published><updated>2010-06-15T18:51:13.534-07:00</updated><title type='text'>Simplified case class Generator for Scalacheck</title><content type='html'>I just wrote a fairly handy generator for making very simple vanilla case classes. It basically uses the apply method defined in the companion of them to make things pretty simple. I am not sure if something similar is in the library already.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;basically you can just type in your specification.&lt;br /&gt;&lt;br /&gt;implicit val arbPoint = ArbFunc(Point.apply _)&lt;br /&gt;&lt;br /&gt;and then arbitrary points will be provided as needed&lt;br /&gt;&lt;br /&gt;If I posted the code here i have feeling it would get severely mangled so I put it in a gist:&lt;br /&gt;&lt;br /&gt;http://gist.github.com/440002&lt;br /&gt;&lt;br /&gt;I think it is a simpler way to make the generators for case classes where you don't care that much about constraining the members of the case class.&lt;br /&gt;&lt;br /&gt;posted to the mailing list, waiting for moderation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-1993514186709862864?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/1993514186709862864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=1993514186709862864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1993514186709862864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1993514186709862864'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2010/06/simplified-case-class-generator-for.html' title='Simplified case class Generator for Scalacheck'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-728380210525335696</id><published>2010-06-14T13:45:00.000-07:00</published><updated>2010-06-14T13:45:13.656-07:00</updated><title type='text'>Working around Dependent Method Types with Structural Types</title><content type='html'>Until dependent method types move out of experimental status in the scala compiler (they can be enabled with -Xexperimental)&amp;nbsp;we have been using Structural Typing to work around their absence. &lt;br /&gt;&lt;br /&gt;Here's how were doing it:&lt;br /&gt;&lt;br /&gt;First, Given:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;trait AToB {&lt;br /&gt;    type B&lt;br /&gt;    def b : B&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;and an implementation:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;trait AToInt extends AToB {&lt;br /&gt;    final override type B = Int&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object AToInt {&lt;br /&gt;    def apply(x : Int) = new AToInt {&lt;br /&gt;        final override val b = x&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We would like to write a function with given any AToB&lt;br /&gt;returns the type of B specified by that A:&lt;br /&gt;&lt;br /&gt;if we had dependent method types we could write this as&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;def bOf[A &amp;lt;: AToB](a : A) : a.B = a.b&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;however this gives the error:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;error: illegal dependent method type&lt;br /&gt;          def bOf[A &amp;lt;: AToB](a : A) : a.B = a.b&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;To work around this however and still preserve type safety we have been doing this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;def bOf[AA &amp;lt;: AToB {type B = BB}, BB](a : AA) : BB = a.b&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Basically we are using a structural type to fix the abstract type B in AToB to a concrete&lt;br /&gt;type BB. This will enforce the type constraint that we want. There is one annoyance that remains&lt;br /&gt;however and I haven't figured out a solution for it yet, the compiler is inferring the wrong type&lt;br /&gt;for BB.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;val x : Int = bOf(AToInt(5))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;gives the compiler error:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;error: inferred type arguments [java.lang.Object with AToInt,Nothing] do not conform to method bOf's type parameter bounds [AA &amp;lt;: AToB{type B = BB},BB]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;yuck, the work around is to say:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;val x : Int = bOf[AToInt, AToInt#B](AToInt(5))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Which will compile correctly.&lt;br /&gt;&lt;br /&gt;A few more examples which will not compile:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;trait AToString extends AToB {&lt;br /&gt;    final override type B = String&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object AToString {&lt;br /&gt;    def apply(x : String) = new AToString {&lt;br /&gt;        final override val b = x&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//Will not compile&lt;br /&gt;val x : String = bOf[AToInt, AToInt#B](AToInt(5))&lt;br /&gt;//Will compile&lt;br /&gt;val x : String = bOf[AToString, AToString#B](AToString("Good Times"))&lt;br /&gt;//Will not compile&lt;br /&gt;val x : Int = bOf[AToString, AToString#B](AToString("Good Times"))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-728380210525335696?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/728380210525335696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=728380210525335696' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/728380210525335696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/728380210525335696'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2010/06/working-around-dependent-method-types.html' title='Working around Dependent Method Types with Structural Types'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-8265697421293664795</id><published>2010-02-03T00:58:00.000-08:00</published><updated>2010-02-03T01:28:48.502-08:00</updated><title type='text'>Pot of coffee gone, Intellij + Scala + sbt + bash-support plugin = Continuous Unit Testing In The IDE</title><content type='html'>Got it working, sweet, no more neck strain looking back and forth from the terminal on every error, just their just a quick press away, don't even have to move the mouse and Intellij uses next occurrence to traverse between stacktrace elements in the active console.&lt;br /&gt;&lt;br /&gt;Here's the patch for sbt it anyone is interested.&lt;br /&gt;&lt;a href="http://gist.github.com/293488"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;http://gist.github.com/293488&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;bedtime...&lt;br /&gt;&lt;br /&gt;(previous post:&amp;nbsp;&lt;a href="http://scalide.blogspot.com/2010/02/trying-to-get-sbt-to-run-in-intellij.html"&gt;http://scalide.blogspot.com/2010/02/trying-to-get-sbt-to-run-in-intellij.html&lt;/a&gt;)&lt;br /&gt;(bash-support plugin for intellij &lt;a href="http://plugins.intellij.net/plugin/?id=4230"&gt;http://plugins.intellij.net/plugin/?id=4230&lt;/a&gt;)&lt;br /&gt;(mailing list posting&amp;nbsp;&lt;a href="http://groups.google.com/group/simple-build-tool/browse_thread/thread/a0cdaccc76c2384a"&gt;http://groups.google.com/group/simple-build-tool/browse_thread/thread/a0cdaccc76c2384a&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-8265697421293664795?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/8265697421293664795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=8265697421293664795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/8265697421293664795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/8265697421293664795'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2010/02/pot-of-coffee-gone-intellij-scala-sbt.html' title='Pot of coffee gone, Intellij + Scala + sbt + bash-support plugin = Continuous Unit Testing In The IDE'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-8807993307150271738</id><published>2010-02-02T22:34:00.000-08:00</published><updated>2010-02-02T22:34:36.684-08:00</updated><title type='text'>Trying to get sbt to run in intellij with navigable errors and continuous compiles.</title><content type='html'>So close, time to brew another pot of coffee, roll up my sleeves, and get to hacking!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/simple-build-tool/browse_thread/thread/a0cdaccc76c2384a"&gt;http://groups.google.com/group/simple-build-tool/browse_thread/thread/a0cdaccc76c2384a&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The dream of a 95% of the way there realtime compilation / unit test runner for scala in intellij is soooo close!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-8807993307150271738?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/8807993307150271738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=8807993307150271738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/8807993307150271738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/8807993307150271738'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2010/02/trying-to-get-sbt-to-run-in-intellij.html' title='Trying to get sbt to run in intellij with navigable errors and continuous compiles.'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-1430004906828971915</id><published>2010-01-20T16:11:00.000-08:00</published><updated>2010-01-20T16:11:43.290-08:00</updated><title type='text'>A Better Scala Enumeration Type</title><content type='html'>I am going to post a link to the Enum type that I wrote due to the limitations of the builtin Scala Version. I don't use the built in enumeration type anymore as I find it very limiting.&lt;br /&gt;&lt;br /&gt;(source &amp;amp; test / example):&lt;br /&gt;&lt;a href="http://gist.github.com/282446"&gt;http://gist.github.com/282446&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Originally I wrote this as answer to &lt;a href="http://stackoverflow.com/questions/2100730/how-to-get-enumeration-values-enumeration-definition"&gt;this question&lt;/a&gt; on StackOverflow, however felt that it would be useful here too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-1430004906828971915?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/1430004906828971915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=1430004906828971915' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1430004906828971915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1430004906828971915'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2010/01/better-scala-enumeration-type.html' title='A Better Scala Enumeration Type'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-4155738709422126890</id><published>2010-01-05T23:46:00.000-08:00</published><updated>2010-01-05T23:53:20.806-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala programming'/><title type='text'>Follow up to Product.hashCode collisions</title><content type='html'>&lt;span style="font-family: inherit;"&gt;After some experimentation here is the result that I came up. Note that you might need to increase the Heap Space to get it to run in the interpreter because of sort / removeDuplicates.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I posted it as a &lt;a href="http://gist.github.com/270117"&gt;gist&lt;/a&gt;&amp;nbsp;[http://gist.github.com/270117]&lt;br /&gt;&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;You should be able to just copy and paste it into a scala 2.8 interpreter&lt;br /&gt;This yields a result of:&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: inherit;"&gt;(ideal = 1000000.0, actual = 999880, uniqueRatio = 0.99988)&lt;br /&gt;meaning a collision rate &amp;lt; .1%&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-4155738709422126890?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/4155738709422126890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=4155738709422126890' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/4155738709422126890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/4155738709422126890'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2010/01/follow-up-to-producthashcode-collisions.html' title='Follow up to Product.hashCode collisions'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-8653344771731605241</id><published>2010-01-05T22:02:00.000-08:00</published><updated>2010-01-05T22:05:55.551-08:00</updated><title type='text'>Possible Collision Issue with Product.hashCode</title><content type='html'>First Off I am no expert at hashing algo's &amp; perhaps this is some sort of Birthday Problem so I am not sure if what I am pointing out is actually a big issue. It would be interesting to see what would happen on a project that uses large hash maps with Products in it if the distribution at the bottom was improved.&lt;br /&gt;&lt;br /&gt;Quick Summary: &lt;br /&gt;Right now it seems like the hashCode for Products of Arity N is the same regardless of the actual class implementing it &amp; that it doesn't distribute very well:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;case class Point(x : Int, y : Int)&lt;br /&gt;case class Point2(x : Int, y : Int)&lt;br /&gt;(1,2).hashCode == Point(1,2).hashCode == Point2(1,2).hashCode == 3405&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Welcome to Scala version 2.8.0.r20331-b20100101020206 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_15).&lt;br /&gt;List((1,2), (2,1), Point(1,2), Point(2,1), Point2(1,2), Point2(2,1)).map(_.hashCode)&lt;br /&gt;res0: List[Int] = List(3405, 3445, 3405, 3445, 3405, 3445)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In a little more depth: I think this behavior is much better than in 2.7.5 where the ordering of the product elements did not affect the hashCode. (Point(x,y) would clash with Point(y,x))&lt;br /&gt;&lt;br /&gt;in 2.7.5:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;res0: List[Int] = List(1838716253, 1838716293, -1163646902, -1163646862, -270917823, -270917783)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Digging a little further on what this means for a distribution =&gt; &lt;br /&gt;&lt;br /&gt;Keep in mind that a big problem is that java's Integer.hashCode == the number being hashed, which is going to cause problems.&lt;br /&gt;&lt;br /&gt;Using this code to get rudimentary collision distribution:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;val tot = 500&lt;br /&gt;val ideal = tot * tot * 1.0&lt;br /&gt;val hashes = (for(x &lt;- -(tot/2) until (tot/2); y &lt;- -(tot/2) until (tot/2)) yield (x,y).hashCode ).toList&lt;br /&gt;val hset = Set() ++ hashes&lt;br /&gt;val hsSize = hset.size &lt;br /&gt;val hlSize = hashes.removeDuplicates.size&lt;br /&gt;println((ideal, hsSize, hsSize/ideal, hlSize, hlSize/ideal))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here is the 2.7.5 result (takes a few minutes on a Core i7 920, removeDuplicates is terribly slow):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(250000.0, 20959,0.083836,20959,0.083836)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and Here is the 2.8 nightly result (surprisingly the same distribution, that takes only a few seconds):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(250000.0, 20959,0.083836,20959,0.083836)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Both cases are going to collide 90+% of the time (notice that changing tot to 100 reduces the collision % quite significantly so I suspect there is a quadratic relationship at play here)&lt;br /&gt;&lt;br /&gt;Running with a tot =100 gives:&lt;br /&gt;&lt;code&gt;(10000.0,4159,0.4159,4159,0.4159)&lt;/code&gt;&lt;br /&gt;Still a 58% collide rate, but a lot better than the larger case.&lt;br /&gt;&lt;br /&gt;Finally for the 3 Tuple cases with tot = 100&lt;br /&gt;&lt;code&gt;(1000000.0,170578,0.170578,170578,0.170578)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Perhaps I should look into a better case than just integers to see what the collision rates actually are like.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-8653344771731605241?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/8653344771731605241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=8653344771731605241' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/8653344771731605241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/8653344771731605241'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2010/01/possible-collision-issue-with.html' title='Possible Collision Issue with Product.hashCode'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-256118623767254994</id><published>2009-12-02T02:14:00.000-08:00</published><updated>2009-12-02T02:19:32.873-08:00</updated><title type='text'>The Magic Mixin, Simple Version</title><content type='html'>For boilerplate equality of classes, where the performance of equals is not all that important. I use a simple trait that I implement a few methods from. It's pretty handy so I figured I would post it.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Check out the &lt;a href="http://gist.github.com/247104"&gt;Gist&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-256118623767254994?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/256118623767254994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=256118623767254994' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/256118623767254994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/256118623767254994'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2009/12/magic-mixin-simple-version.html' title='The Magic Mixin, Simple Version'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-7192797768460098297</id><published>2009-07-10T14:22:00.000-07:00</published><updated>2009-07-10T14:24:47.926-07:00</updated><title type='text'>Updates on the Intellij Plugin, Error Console is Less Grabby</title><content type='html'>It's still a work in progress but I have managed to make the errors window less grabby. Right now it prints some harmless messages to standard out, just ignore them.&lt;br /&gt;&lt;br /&gt;As before:&lt;br /&gt;&lt;br /&gt;If you are an Intellij user and want to check out the modified plugin, here is the &lt;a href="http://github.com/benjaminjackman/EclipseMode/tree/master"&gt;source&lt;/a&gt; and here is a &lt;a href="http://benjaminjackman.github.com/download/eclipseMode.jar"&gt;download&lt;/a&gt; of a jar that you can drop in your /plugins folder&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-7192797768460098297?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/7192797768460098297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=7192797768460098297' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/7192797768460098297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/7192797768460098297'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2009/07/updates-on-intellij-plugin-error.html' title='Updates on the Intellij Plugin, Error Console is Less Grabby'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-3368242446382225311</id><published>2009-07-09T22:24:00.000-07:00</published><updated>2009-07-09T22:37:59.887-07:00</updated><title type='text'>Intellij Plugin</title><content type='html'>I recently switched to using Intellij 8 for scala development from Eclipse. On the whole it is a lot more polished than the current incarnation of the Scala IDE for Eclipse, I recommend it highly. Out of the 3 big java IDEs Intellij has the best Scala support at the moment. I will try out the Scala IDE for Eclipse again, once Miles gets done with all the refactoring he is doing.&lt;br /&gt;&lt;br /&gt;One of the features I missed most from Eclipse was how eclipse compiles automatically in the background when files are saved. Luckily there is a plugin for Intellij (mentioned in this &lt;a href="http://www.jetbrains.com/idea/documentation/migration_faq.html"&gt;faq&lt;/a&gt;) called &lt;a href="http://plugins.intellij.net/plugin/?id=3822"&gt;EclipseMode&lt;/a&gt; to add that behaviour, though it has a few kinks. [1]&lt;br /&gt;&lt;br /&gt;I wasn't able to fix all of the issues I have with it (yet), however I did make one simple change that adds a toggle for it (called Compile On Save) to the build menu.&lt;br /&gt;&lt;br /&gt;If you are an Intellij user and want to check out the modified plugin, here is the &lt;a href="http://github.com/benjaminjackman/EclipseMode/tree/master"&gt;source&lt;/a&gt; and here is a &lt;a href="http://benjaminjackman.github.com/download/eclipseMode.jar"&gt;download&lt;/a&gt; of a jar that you can drop in your &lt;idea-install-directory&gt;/plugins folder&lt;br /&gt;&lt;br /&gt;[1] &lt;span style="font-weight: bold;"&gt;kinks&lt;br /&gt;&lt;/span&gt;One caveat, as others have mentioned: Is there any way to keep the messages window from auto-opening and from stealing focus? I tried mucking around with the plugin source, and couldn't figure it out, seems that problems view is not part of the openAPI and very hard to get to.&lt;br /&gt;&lt;br /&gt;Also it doesn't seem to work with intellij 9, (tho i was able to hack it to get it to work, seems like they changed some of the non open api stuff the plugin uses).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-3368242446382225311?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/3368242446382225311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=3368242446382225311' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/3368242446382225311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/3368242446382225311'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2009/07/intellij-plugin.html' title='Intellij Plugin'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-1913004993186446249</id><published>2009-06-04T01:47:00.000-07:00</published><updated>2009-06-04T02:14:04.729-07:00</updated><title type='text'>GetAnyClass Tip</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:georgia;"&gt;I've been having some trouble with calling getClass on generic/primitive types.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;It seems that it's a &lt;a href="http://lampsvn.epfl.ch/trac/scala/ticket/496"&gt;known&lt;/a&gt; issue with scala that &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;a href="http://lampsvn.epfl.ch/trac/scala/ticket/864"&gt;wontfix&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:georgia;"&gt; and hence this code won't compile&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;def convert[A,B](instance : A, toClass : Class[B]) : Option[B] = {&lt;br /&gt;  //Fails here with the error below&lt;br /&gt;  instance.getClass&lt;br /&gt;  ...Rest of implementation...&lt;br /&gt;}&lt;/blockquote&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;(The error):&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;console&gt;&lt;/console&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;console&gt;:6: error: type mismatch;&lt;br /&gt;found   : A&lt;br /&gt;required: ?{val getClass: ?}&lt;br /&gt;Note that implicit conversions are not applicable because they are ambiguous:&lt;br /&gt;both method any2stringadd in object Predef of type (Any)scala.runtime.StringAdd&lt;br /&gt;and method any2ArrowAssoc in object Predef of type [A](A)ArrowAssoc[A]&lt;br /&gt;are possible conversion functions from A to ?{val getClass: ?}&lt;br /&gt;        instance.getClass&lt;br /&gt;        ^&lt;br /&gt;&lt;/console&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;the problem has a quick fix though suggested by paulp on the #scala irc channel on Freenode:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;you can encapsulate that though:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;scala&gt; def getAnyClass(x: Any) = x.asInstanceOf[AnyRef].getClass&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;getAnyClass: (x: Any)java.lang.Class[_ &lt;: java.lang.Object&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;casting to AnyRef (for this purpose) is a no-op on non-primitives, so...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;you could plant that as an implicit if you want so 1.getAnyClass will work.&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;what this translates to is basically defining a class like this somewhere in your project:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;/** Predef for brewmaster, maybe package objects will obsolete this&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;private[brewmaster] object Brewdef {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  implicit def any2GetAnyClass(x : Any) = new GetAnyClass(x) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    class GetAnyClass(val x : Any) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      def getAnyClass = x.asInstanceOf[AnyRef].getClass&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;then chaning the code above slightly to use the .getAnyClass method it with&lt;br /&gt;&lt;/span&gt;&lt;a id="publishButton" class="cssButton" href="javascript:void(0)" target="" onclick="if (this.className.indexOf(&amp;quot;ubtn-disabled&amp;quot;) == -1) {var e = document['stuffform'].publish;(e.length) ? e[0].click() : e.click(); if (window.event) window.event.cancelBubble = true; return false;}"&gt;&lt;div class="cssButtonOuter"&gt;&lt;div class="cssButtonMiddle"&gt;&lt;div class="cssButtonInner"&gt;Publish Post&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;import Brewdef._&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;def convert[A,B](instance : A, toClass : Class[B]) : Option[B] = {&lt;br /&gt; instance.getAnyClass&lt;br /&gt; ...&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;voila!&lt;br /&gt;this will also allow things like &lt;span style="font-family:courier new;"&gt;5.getAnyClass&lt;/span&gt; to compile (&lt;any&gt;.getClass fails)&lt;br /&gt;&lt;/any&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-1913004993186446249?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/1913004993186446249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=1913004993186446249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1913004993186446249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1913004993186446249'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2009/06/getanyclass-tip.html' title='GetAnyClass Tip'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-6040437981971844441</id><published>2009-06-01T12:30:00.000-07:00</published><updated>2009-06-01T19:09:23.901-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala programming'/><title type='text'>Immutable Objects and Named Parameters in scala</title><content type='html'>--Updated--&lt;br /&gt;Jorge Ortiz pointed out that 2.8 is already going to include a copy method in every case class:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Every case class already comes with a "copy" method defined something like:&lt;br /&gt;&lt;br /&gt;def copy(x: Int = this.x, y: Int = this.y, z: Int = this.z) = {&lt;br /&gt; Point3d(x, y, z)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;And used like:&lt;br /&gt;&lt;br /&gt;p1.copy(z = 2)&lt;br /&gt;&lt;br /&gt;-Jorge Ortiz&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's a cool way the named parameters feature being added in Scala 2.8 might help with immutable objects. It should help clients avoid errors when copying an immutable class, also it should end up hiding them from certain changes in that class.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;//An overly simple example class&lt;br /&gt;case class Point3d(x : Int, val y : Int, val z : Int) {&lt;br /&gt; //Add method like this to make copying immutable classes easier&lt;br /&gt; def copy (x : Option[Int] = None, val y : Option[Int] = None, val z : Option[Int] = None) = {&lt;br /&gt;   Point3d(x.getOrElse(this.x), y.getOrElse(this.y), z.getOrElse(this.z))&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Original class&lt;br /&gt;val p1 = Point3d(1,1,1)&lt;br /&gt;&lt;br /&gt;//"Old Way"&lt;br /&gt;//notice every field is copied, this&lt;br /&gt;//gets nasty as the class acquires more than just 3 fields&lt;br /&gt;//Also notice how directly tied to the factory method&lt;br /&gt;//this style is&lt;br /&gt;val pOld = Point3d(p1.x, p1.y, 2)&lt;br /&gt;&lt;br /&gt;//"New way"&lt;br /&gt;//here we only care about the part of the&lt;br /&gt;//class that we want to change. The class we are&lt;br /&gt;//changing was refactored and additional fields were&lt;br /&gt;//added to it, we would have to change all &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;the "Old Way"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;//calls, however this call will still work fine.&lt;br /&gt;val pNew = p1.copy(z=Some(2))&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-6040437981971844441?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/6040437981971844441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=6040437981971844441' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/6040437981971844441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/6040437981971844441'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2009/06/immutable-objects-and-named-parameters.html' title='Immutable Objects and Named Parameters in scala'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-3803364026282621456</id><published>2009-05-18T17:32:00.000-07:00</published><updated>2009-09-23T20:10:31.903-07:00</updated><title type='text'>Hashcode &amp; Equals in the Scala 2.8 Collections Library</title><content type='html'>[Edit]&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Martin commented that the disparity between equals and hashCode has been changed on the Scala 2.8 trunk so that they now follow the hashCode-equals contract, therefore most of this post is irrelevant.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I just finished reading the &lt;a href="http://permalink.gmane.org/gmane.comp.lang.scala.debate/2882"&gt;whitepaper&lt;/a&gt; on the collections library that is going to be put into scala 2.8&lt;br /&gt;&lt;br /&gt;First let me say that I really enjoy the new collections library, it seems like it is going to be a vast improvement over the old, and give scala one of the nicest, most growable collections libraries of any language out there. I really think that the new library with how well abstracted everything is will be a really cool starting point for allowing users to grow the language and give Scala what will in a very short time could be the end-all be-all of collections libraries.&lt;br /&gt;&lt;br /&gt;Having just watched Guy Steele's talk on &lt;a href="http://video.google.com/videoplay?docid=-8860158196198824415"&gt;Growing A Language&lt;/a&gt; (thanks to &lt;a href="http://twitter.com/debasishg"&gt;debasishg@twitter&lt;/a&gt;) for tweeting it. It seems like Martin Odersky and the other architects of the new library really channelled what he was getting at in his talk. This new library while being fairly complete in it's own right, is going to give users a both the flexibility to implement collections that are highly optimized and/or  the ability to implement them very quickly by reusing existing code. It will let the vendor of the Collection class focus more time on his implementation and less time on having to provide a bazillion methods that clients reasonably expect from a collection class.&lt;br /&gt;&lt;br /&gt;There was a one thing that jumped out at me as being a bad idea in the new library, it was on page 15 and relates to how the new collections library is going to handle hashCode for mutable collections, and equals for all collections.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Per the whitepaper:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;    It does not matter for the equality check whether a collection is mutable or immutable. For a mutable collection one simply considers its current elements at the time the equality test is performed. This means that a mutable collection might be equal to different collections at different times, depending&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;what elements are added or removed. This is a potential trap when using a mutable collection as a key in a hashmap. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Example:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     val map = HashMap[Array[Int], Int]()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     val xs = Array(1, 2, 3)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     map += (xs -&gt; 6)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     xs(0) = 0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     map(xs)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;In this example, the access on the last line will most likely fail because the &lt;/span&gt;hashcode&lt;span style="font-style: italic;"&gt; of the array &lt;/span&gt;xs&lt;span style="font-style: italic;"&gt; has changed in the second-to-last line. Therefore, the &lt;/span&gt;hashcode&lt;span style="font-style: italic;"&gt;-based &lt;/span&gt;lookup&lt;span style="font-style: italic;"&gt; will look at a different place than the one where &lt;/span&gt;xs&lt;span style="font-style: italic;"&gt; was stored.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    To avoid this trap, mutable collection classes will not support taking their &lt;/span&gt;hashCode&lt;span style="font-style: italic;"&gt;—they will throw an &lt;/span&gt;UnsupportedOperationException&lt;span style="font-style: italic;"&gt; with the message “unsuitable as hash key” if &lt;/span&gt;hashCode&lt;span style="font-style: italic;"&gt; is called&lt;/span&gt;&lt;/blockquote&gt;I have a very bad feeling about any class throwing an exception when you ask it for its hashCode, the same way I would have a bad feeling if a class throw an exception just for calling its toString method, or its equals methods. I am generally not a big fan of surprise exceptions and while I am well aware of the dangers of using mutable field in a hash map, I just don't think that the hashCode method should be throwing exceptions. It's going to be a real gotcha for any programmer.&lt;br /&gt;&lt;br /&gt;Programmer add gotcha to brain: &lt;span style="font-style: italic;"&gt;"I can generally call hashCode on any object, except for this sub-type of objects, which are going to throw an exception at me because it is dangerous to use them in hashmaps. If I am writing generic code that calls hashCode on object I need to catch exceptions, because, certain objects decide they really did not want to ever be used in a hashmap, even though my code doesn't mutate them afterwards, as I am just sending these objects right out of the system for serialization and I need a good key to use for them that obeys the contract of hashcode. In this case, I am going to be in trouble as there is now no longer a guaranteed way for me to get hashCode that obeys the &lt;a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode%28%29"&gt;contract of hashCodes/equals&lt;/a&gt;. What do I do?"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Further, If a mutable collection is excluded from being used as a key because it could be mutated after being added to a map, shouldn't any 'case class' with a var field also be Unhashable? (A Case Class in scala provides some syntatic sugar by auto-implementing the equals and hashCodes methods based on the fields of the class.) Isn't Unhashable really just a synonym for Mutable? And is the real issue here forcing all client's to never use a mutable value as a key in a hashmap? And shouldn't then any mutable class throw UnsupportedOperationException when the hashCode of that class is called? Is it really a good idea to enforce this constraint this hard?&lt;br /&gt;&lt;br /&gt;Having said that, and given the subtlety of the errors that happen when programmers do accidentally use mutable values as hash keys, then change them later on, I think that making some sort of bell go off that says: "Warning, you just used a mutable value as a key in a hashmap! I hope you know what you're doing, because you probably just messed up" is a good idea.&lt;br /&gt;&lt;br /&gt;Another thing that scares about the 'This is Unhashable because it is mutable ideology' is that it is going to force everyone to implement their own hash functions for objects that are mutable, or always first coerce them into an immutable version just to get a hashCode (with possible severe performance impacts), if they need to for some reason get a hashCode for that class (maybe for some sort of db serialization scenario, who knows). Since their is no integrated way to get a hashCode for a mutable collection, they now are going to have make their own hashing function, and that is generally a bad idea, as making good hash functions can be hard. It's better to do it right once in the library than to have everyone do it their own way. Can it be said with absolute certainty that just because something is mutable, it must never generate a hashCode for any reason?&lt;br /&gt;&lt;br /&gt;It would be really nice if it could be enforced by the compiler as a constrait on the type parameters of HashMaps, namely the Key type of a hashmap should be able to somehow say something like:&lt;br /&gt;HashMap&lt;span style="font-family:courier new;"&gt;[K &lt;: !&lt;/span&gt;Unhashable&lt;span style="font-family:courier new;"&gt;, V]&lt;/span&gt;&lt;br /&gt;where &lt;span style="font-family:courier new;"&gt;K &lt;: !&lt;/span&gt;Unhashable means K is not a subtype of Unhashable, and the compiler enforces the constraint, rather than the runtime.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The other thing that stuck out was a potential gotcha around the way equality is handled.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The &lt;/span&gt;Whitepaper&lt;span style="font-weight: bold;"&gt; on Equality:&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;The collection libraries have a uniform approach to equality and hashing. The idea is, first, to divide collections into sets, maps, and sequences. Collections in different categories are always unequal. For instance, Set(1, 2, 3) is unequal to List(1, 2, 3) even though they contain the same elements. On the other hand, within the same category, collections are equal if and only if they have the same elements (for sequences: the same elements in the same &lt;/span&gt;oder&lt;span style="font-style: italic;"&gt;). For example, List(1, 2, 3) == Array(1, 2, 3), and &lt;/span&gt;HashSet&lt;span style="font-style: italic;"&gt;(1, 2) == &lt;/span&gt;Treeset&lt;span style="font-style: italic;"&gt;(2, 1).&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;From above: seems that a List(1,2,3) will now equal an Array(1,2,3) while they have different hashCodes (List is some defined value, and Array is Nothing because it throws an exception) which &lt;a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode%28%29"&gt;violates the contract of hashCode&lt;/a&gt;. Maybe this doesn't matter that much in this case because the mutable collections can never be used in a hashmap, but what about two different implementations of an immutable collection within the same category? If this is the direction being taken, then clients probably should never should override equals or hashCode for their own implementations of collections. Conceptually equals and hashCode should be final at the level of Map, Set, and Sequence otherwise any client who writes their own version of a collection inheriting from one of these has to ensure that they generate the same hashCode for all other collections of the same category that contain the same values or else they risk breaking the contract put forth in the whitepaper.&lt;br /&gt;&lt;br /&gt;Another approach might be to just make a method in Sequence, Map, &amp;amp; Set called sameElements (or deepEquals or equalElems or whatever) that returns true iff these two collections are of the same category and contain the same elements.&lt;br /&gt;&lt;br /&gt;I am not really sure which is preferable, on the one hand I like the idea of treating all sets, maps, and sequences uniformly, in the sense that if they have the same values, then they are the same, on the other hand, It still would be nice to quickly tell if certain maps have the same ordering as well they are iterated across (I suppose that something like this could probably do that as well):&lt;br /&gt;&lt;span style="font-style: italic;"&gt;pseudocode&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;def sameOrder = (map1.iterator zip map2.iterator).find((e1, e2) =&gt; {e1 != e2}).isEmpty&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-3803364026282621456?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/3803364026282621456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=3803364026282621456' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/3803364026282621456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/3803364026282621456'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2009/05/hashcode-equals-in-scala-28-collections.html' title='Hashcode &amp; Equals in the Scala 2.8 Collections Library'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-5474190862912339826</id><published>2009-05-07T20:30:00.000-07:00</published><updated>2009-05-07T20:41:02.175-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala scalide programming java jvm interpreter ide'/><title type='text'>Planning to do a scalide screencast sometime</title><content type='html'>I am hoping to learn how to record a brief 5 minute screen cast in the next few weeks to walk through some of the features of the interpreter. I know that the user interface leaves a lot to be desired and I haven't had much time to work on it, however hopefully I can explain it better for people new to Scala as it can be a good way to help learn the language. (I use it as a calculator now). To people who have used mathematica before the interface might be only extremely horrible, for everyone else it's probably entirely unusable ;-)&lt;br /&gt;&lt;br /&gt;I am also going to look over the recent changes that have been checked into the scala tools package by extempore to see if I can add some auto-complete support which would make the interpreter much more usuable, stay tuned :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-5474190862912339826?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/5474190862912339826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=5474190862912339826' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/5474190862912339826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/5474190862912339826'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2009/05/planning-to-do-scalide-screencast.html' title='Planning to do a scalide screencast sometime'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-1503696155861434071</id><published>2008-09-30T11:54:00.000-07:00</published><updated>2008-09-30T11:56:45.639-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala scalide programming java jvm interpreter ide'/><title type='text'>New Scalide Release</title><content type='html'>I released newer updated version of Scalide a few weeks ago with a newer version of the Scala interpreter so &lt;a href="http://code.google.com/p/scalide/"&gt;check it out&lt;/a&gt; and let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-1503696155861434071?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/1503696155861434071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=1503696155861434071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1503696155861434071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1503696155861434071'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2008/09/new-scalide-release.html' title='New Scalide Release'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-7949658997172632186</id><published>2008-05-19T23:01:00.000-07:00</published><updated>2008-05-19T23:29:42.439-07:00</updated><title type='text'>Another update</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_fbCXAuGdwog/SDJvzHAX9dI/AAAAAAAAA_o/sBUH2Ew9ND8/s1600-h/Screenshot-Scalide.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_fbCXAuGdwog/SDJvzHAX9dI/AAAAAAAAA_o/sBUH2Ew9ND8/s320/Screenshot-Scalide.png" alt="" id="BLOGGER_PHOTO_ID_5202343443410974162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Probably the last one of the night, just clarified a few things in help.&lt;br /&gt;&lt;a href="http://scalide.googlecode.com/files/scalide-2008-05-20_00-59-10.jar"&gt;http://scalide.googlecode.com/files/scalide-2008-05-20_00-59-10.jar&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-7949658997172632186?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/7949658997172632186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=7949658997172632186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/7949658997172632186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/7949658997172632186'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2008/05/another-update_19.html' title='Another update'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_fbCXAuGdwog/SDJvzHAX9dI/AAAAAAAAA_o/sBUH2Ew9ND8/s72-c/Screenshot-Scalide.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-4738727528420778158</id><published>2008-05-19T22:39:00.001-07:00</published><updated>2008-05-19T22:39:53.655-07:00</updated><title type='text'>Another update</title><content type='html'>Fixed a few more bugs and added the ability to erase cells&lt;br /&gt;&lt;br /&gt;&lt;a href="http://scalide.googlecode.com/files/scalide-2008-05-20_00-36-12.jar"&gt;http://scalide.googlecode.com/files/scalide-2008-05-20_00-36-12.jar&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-4738727528420778158?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/4738727528420778158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=4738727528420778158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/4738727528420778158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/4738727528420778158'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2008/05/another-update.html' title='Another update'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-1294194075156575126</id><published>2008-05-19T18:59:00.000-07:00</published><updated>2008-05-19T19:00:48.264-07:00</updated><title type='text'>Updated Release Tonight</title><content type='html'>I just released a new version that adds several minor enhancements and fixes some hang on input issues.&lt;br /&gt;&lt;br /&gt;Check it out here:&lt;br /&gt;&lt;a href="http://scalide.googlecode.com/files/scalide-2008-05-19_20-55-32.jar"&gt;http://scalide.googlecode.com/files/scalide-2008-05-19_20-55-32.jar&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-1294194075156575126?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/1294194075156575126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=1294194075156575126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1294194075156575126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/1294194075156575126'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2008/05/updated-release-tonight.html' title='Updated Release Tonight'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-5773930719220061638</id><published>2008-05-15T22:38:00.000-07:00</published><updated>2008-05-16T00:08:18.185-07:00</updated><title type='text'>New Version With Saving/Loading</title><content type='html'>I just finished a new version that can save and load interpreter sessions.&lt;br /&gt;&lt;br /&gt;Check it out here:&lt;br /&gt;&lt;a href="http://scalide.googlecode.com/files/scalide-2008-05-16_00-33-32.jar"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://scalide.googlecode.com/files/scalide-2008-05-16_02-05-36.jar"&gt;http://scalide.googlecode.com/files/scalide-2008-05-16_02-05-36.jar&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-5773930719220061638?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/5773930719220061638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=5773930719220061638' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/5773930719220061638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/5773930719220061638'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2008/05/new-version-with-savingloading.html' title='New Version With Saving/Loading'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2314459346745910857.post-830941689355617279</id><published>2008-05-15T06:53:00.000-07:00</published><updated>2008-05-15T06:58:38.161-07:00</updated><title type='text'>First post</title><content type='html'>I am going to use this blog to discuss topics related to the Scala programming language and my pet project I am using to learn called Scalide which is a visual front-end to the Scala interpreter. Check it out at &lt;a href="http://scalide.googlecode.com"&gt;http://scalide.googlecode.com&lt;/a&gt; and discuss it at &lt;a href="http://groups.google.com/group/scalide"&gt;http://groups.google.com/group/scalide&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2314459346745910857-830941689355617279?l=scalide.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scalide.blogspot.com/feeds/830941689355617279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2314459346745910857&amp;postID=830941689355617279' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/830941689355617279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2314459346745910857/posts/default/830941689355617279'/><link rel='alternate' type='text/html' href='http://scalide.blogspot.com/2008/05/first-post.html' title='First post'/><author><name>Ben Jackman</name><uri>http://www.blogger.com/profile/11000882649989928707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
