<?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-1673113361032868171</id><updated>2012-01-26T10:45:39.138-05:00</updated><category term='EasyMock'/><category term='dad'/><category term='goat rodeo'/><category term='scalac'/><category term='rumble'/><category term='singleton'/><category term='annotations'/><category term='maven'/><category term='higher kinded types'/><category term='privacy'/><category term='migrate'/><category term='duck-typing'/><category term='antipattern'/><category term='presentation'/><category term='dogfood'/><category term='statics'/><category term='grails'/><category term='inheritance'/><category term='scalatypes'/><category term='osgi'/><category term='ejb'/><category term='for-comprehension'/><category term='spring'/><category term='rails'/><category term='m2e'/><category term='sun'/><category term='virtual appliance'/><category term='macro'/><category term='traits'/><category term='eclipse'/><category term='xhtml'/><category term='typesafe'/><category term='java.jigsaw'/><category term='archiva'/><category term='c++'/><category term='work'/><category term='novajug'/><category term='project coin'/><category term='antlrworks'/><category term='horrible misinterpretation'/><category term='xml'/><category term='jcp'/><category term='ajp'/><category term='virtualbox'/><category term='fx script'/><category term='scala'/><category term='threads'/><category term='jsf'/><category term='java'/><category term='bad'/><category term='protocopter'/><category term='vmware'/><category term='init.d'/><category term='theme'/><category term='scope'/><category term='continous integration'/><category term='jcpa'/><category term='lolcode'/><category term='best practices'/><category term='curried functions'/><category term='mojo'/><category term='JavaCC'/><category term='new user'/><category term='best buy'/><category term='oracle'/><category term='squid'/><category term='NAT'/><category term='interpreter'/><category term='trac'/><category term='type traits'/><category term='db:migrate'/><category term='implicitNotFound'/><category term='jpa'/><category term='groovy'/><category term='faults'/><category term='dsl'/><category term='design'/><category term='testing'/><category term='ubuntu'/><category term='j2ee'/><category term='extjs'/><category term='json'/><category term='agent'/><category term='duck typing'/><category term='svn'/><category term='google'/><category term='challenge'/><category term='proxy'/><category term='podcast'/><category term='RRID'/><category term='type classes'/><category term='javascript'/><category term='winstone'/><category term='actors'/><category term='monad'/><category term='Option'/><category term='ARM'/><category term='tomcat'/><category term='template'/><category term='application'/><category term='types'/><category term='optional.'/><category term='GTK'/><category term='tasks'/><category term='string'/><category term='confuse'/><category term='iam'/><category term='io language'/><category term='generics.'/><category term='hdmi'/><category term='ivy'/><category term='mutex'/><category term='python'/><category term='plugin'/><category term='comparison'/><category term='issues'/><category term='scoped objects'/><category term='knight rider'/><category term='script'/><category term='slave'/><category term='hardy heron'/><category term='compiz'/><category term='prototype oo'/><category term='firewall'/><category term='embed'/><category term='jee 6'/><category term='apache'/><category term='javafx'/><category term='debug'/><category term='dependency injection'/><category term='hibernate'/><category term='JVM'/><category term='ant'/><category term='guide'/><category term='implicits'/><category term='ext'/><category term='jigasw'/><category term='ajax'/><category term='comcast'/><category term='Junit'/><category term='loan pattern'/><category term='repl'/><category term='metaprogramming'/><category term='ssh'/><category term='scalac plugins'/><category term='modules'/><category term='lisp'/><category term='hudson'/><category term='antlr3'/><category term='JeOS'/><category term='book'/><category term='slackware'/><category term='pattern matching'/><category term='delimited continuations'/><category term='implicit'/><category term='partial functions'/><category term='shorewall'/><category term='closure'/><category term='jboss'/><category term='server'/><category term='composition'/><category term='bootstrap'/><category term='collections'/><category term='fail'/><category term='monkey patching'/><category term='functional vs. oo'/><title type='text'>Rants, Raves and Ridicule</title><subtitle type='html'>My thoughts and/or rants on Software Development.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>96</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-2175543995967670019</id><published>2011-12-21T22:16:00.002-05:00</published><updated>2011-12-21T22:16:15.922-05:00</updated><title type='text'>Migrating to new site</title><content type='html'>Hey guys, I'm finally moving off of blogger. &amp;nbsp; The new blog will be located at &lt;a href="http://jsuereth.com/"&gt;http://jsuereth.com&lt;/a&gt;&amp;nbsp;and the source code is available at &lt;a href="http://github.com/jsuereth/jsuereth.github.com"&gt;http://github.com/jsuereth/jsuereth.github.com&lt;/a&gt;. &amp;nbsp; Feel free to fork what you want, and send back pull requests if you do something nice :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-2175543995967670019?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/2175543995967670019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=2175543995967670019' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2175543995967670019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2175543995967670019'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/12/migrating-to-new-site.html' title='Migrating to new site'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-1099806865674280113</id><published>2011-12-07T13:59:00.001-05:00</published><updated>2011-12-07T16:42:52.002-05:00</updated><title type='text'>Scala Fresh is alive</title><content type='html'>It seems a lot of posts I've meant to write for a *long* time have been able to be used optimally in response to other blogs. &lt;br /&gt;&lt;br /&gt;Todays post is brought to you by David Pollak's &lt;a href="http://t.co/qjBQJomR"&gt;fragility post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So let's talk about the problem of "Binary Compatibility(TM)" in Scala.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;First off, David raises a big issue in Scala. &amp;nbsp;One that most of us have seen. &amp;nbsp;Scala's new language features necessarily break binary compatibility of the bytecode. &amp;nbsp;Adding things like Specialization change Scala's standard library enough that you cannot use code compiled against older versions with the new version. &amp;nbsp; This is a two-edged sword.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Scala experience should be as smooth as possible for all customers.&lt;/li&gt;&lt;li&gt;Things like java.util.Date shouldn't survive endlessly our standard library.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This requires a careful balance between breaking binary compatibility and advancing the language. &amp;nbsp; So far, I'm pretty happy with the way this has been done, but would like to see things stabilize in the future. &amp;nbsp;Let's take a look at what's happened:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Scala's new binary compatible releases&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Scala 2.9.1 is binary compatible with Scala 2.9.0. &amp;nbsp; If you compile code against Scala 2.9.0, you can use it with the standard library from Scala 2.9.1. &amp;nbsp; This will hold for *all* 2.9.x releases. &amp;nbsp; In Scala, binary compatibility will be at the bug-fix release. &amp;nbsp;All 2.10.x releases will be binary compatible with previous 2.10 releases. &amp;nbsp;This means that as long as your dependencies are compiling for a given Scala minor version, then you can continue to enjoy binary compatibility of libraries. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This was made possible by the freely available &lt;a href="http://downloads.typesafe.com/migration-manager/0.1/migration-manager-0.1.jar"&gt;Migration Manager tool&lt;/a&gt;. &amp;nbsp;A lot of us at typesafe use the&amp;nbsp;publicly&amp;nbsp;available version when developing to ensure binary compatibility of libraries.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note: &amp;nbsp;This was *not* true for a lot of David Pollak's Scala experience, and is the result of many of us&amp;nbsp;petitioning&amp;nbsp;for better binary compatibility. &amp;nbsp;It's my opinion that this guarantee solves 50-80% of the problem.&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;What happened to Scala fresh?&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I've begun work on what can only be called "Scala Fresh 2.0". &amp;nbsp;That is, a place where community libraries will be built and deployed against the latest version of Scala. &amp;nbsp; This can serve two purposes:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Ensure that future versions of Scala do not break community libraries&lt;/li&gt;&lt;li&gt;Ensure that the core libraries of Scala are available for every major version of Scala.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;You can find the project publicly available&amp;nbsp;&lt;a href="https://github.com/jsuereth/scala-cel"&gt;here&lt;/a&gt;. &amp;nbsp;All of the work is public and will be migrate to the "scala" user on github once complete and ready for more contributions. &amp;nbsp;Feel free to contribute or offer suggestions. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;People may not realize but Scala Fresh failed because *I* failed Scala Fresh. &amp;nbsp; I had very little time between a more than full time commitment at Google, &lt;a href="http://www.manning.com/suereth"&gt;writing commitments&lt;/a&gt;, and kids. &amp;nbsp;This should not be an issue in the future, thanks to Typesafe taking binary compatibility seriously. &amp;nbsp;I now have a &lt;a href="https://github.com/jsuereth/scala-cel/blob/master/project/Build.scala"&gt;prototype build&lt;/a&gt; that you can migrate your projects into.&lt;br /&gt;&lt;br /&gt;My coworker likens this idea to linux distribution repositories. &amp;nbsp;I think it's a decent way to think of it. &amp;nbsp;I, and others, are working hard to ensure the ecosystem for every major Scala release is easy to use and stable. &amp;nbsp; Migrating major Scala versions should be as difficult as finding deprecation warnings and removing them.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;SBT cross releasing&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Mark Harrah, recognized that Scala remains generally *source* compatible between major releases (2.8 to 2.9). &amp;nbsp; A *long* time ago, Mark met me at a Panera in Anne Arundel, MD to discuss a mechanism of cross deploying libraries so that they were available for every release of Scala. &amp;nbsp; This was well before the 2.9.x binary compatibility days and is still in heavy use within the community. &amp;nbsp; It's been pretty widely adopted, but can only go so far. &amp;nbsp; It's a good stop-gap solution that we, the community, can improve on.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Binary compatibility is a community effort. &amp;nbsp;I know Typesafe is doing what it can with its resources, and I'm personally tackling as much as I can (probably trying to juggle too many balls). &amp;nbsp;However, if you want to help, please email me! &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The JVM is amazing, don't doubt its powers&lt;/b&gt;&lt;br /&gt;Finally, I want to clarify a confusion that a lot of people have about binary compatibility. &amp;nbsp;That is, that traits are *HUGE ISSUES FOR BINARY COMPATIBILITY ZOMG!!!*. &amp;nbsp; In actuality, traits are only slightly more dangerous than interfaces + implementation pairs.&lt;br /&gt;&lt;br /&gt;In the code below, the method colored in red was added in a bug-fix release. &amp;nbsp; It is *binary compatible* with the previous version.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;trait Foo {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; def foo = "foo"&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #660000; font-family: 'Courier New', Courier, monospace;"&gt;&lt;i&gt;&amp;nbsp; def bar = "NEW BAR IS NEW BAR!"&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That's right, adding methods, even with implementation, does &lt;b&gt;*NOT*&lt;/b&gt; break linkage. &amp;nbsp;Think about it. &amp;nbsp;How did Java support JDBC 4.0 interfaces running JDBC 3.0 drivers? &amp;nbsp; The trick is that trait-linkage errors happen at&amp;nbsp;&lt;b&gt;*runtime*&lt;/b&gt;&amp;nbsp;when &lt;b&gt;*calling*&lt;/b&gt; a method that has no linked implementation. &amp;nbsp;This is the kind of magic that Java can get away with to ensure binary compatibility and it's just as useful in Scala.&lt;br /&gt;&lt;br /&gt;Now, there is an issue where you can break binary compatibility. &amp;nbsp; Again, red italics will denote new code&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;trait Bar {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; def foo = {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: #660000;"&gt;&lt;i&gt;bar + &lt;/i&gt;&lt;/span&gt;" foo"&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: #660000; font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; def bar = "NEW BAR IS NEW BAR!"&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;NOW, the implementation of a previous method calls a new method. &amp;nbsp; While this new method has an implementation in the trait, compiled code against the trait does not. &amp;nbsp; This is akin to the following Java scenario:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;interface Foo {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; public String foo();&lt;/span&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="color: #660000; font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; public String bar();&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;abstract public class AbstractFoo implements Foo {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; @Override public String foo() { return &lt;i&gt;&lt;span class="Apple-style-span" style="color: #660000;"&gt;bar() +&lt;/span&gt;&lt;/i&gt; " foo" }&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;The abstract method implements one of the trait's methods, but not the new one. &amp;nbsp;However, the implementation is modified to call the new method. &lt;br /&gt;&lt;br /&gt;Scala's collections underwent a minor change in 2.10 to improve both class file size *and* unintentionally binary compatibility. &amp;nbsp; That is, the collections now follow this pattern:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;trait Traversable[A] ....&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;abstract class AbstractTraversable[A] extends Traversable[A] {}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;class Vector[A] extends AbstractTraversable[A] with Traversale[A]....&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this scenario, if your collection extends an Abstract collection (rather than its own parent class), you can remain binary compatble *and allow* new methods to be added to a trait *and be called* be the implementation. &amp;nbsp; Vector is now "binary resilient" to changes in the Traversable trait. &amp;nbsp;There are no guarantees that a trait is not used directly, so we can't take advantage of this when fixing bugs in collections in the Scala library. &amp;nbsp; It's still a nice trick to use.&lt;br /&gt;&lt;br /&gt;You *do* lose some&amp;nbsp;flexibility&amp;nbsp;doing this. &amp;nbsp; Specifically, you can't have multiple class parents unless they're linear (like Java). &lt;br /&gt;&lt;br /&gt;So, my point is that Binary Compatibility is a community issue. &amp;nbsp;The JVM and Scala do what they can. I hope to see the compiler do more in the future. &amp;nbsp; The Migration Manager tool from Typesafe can detect a lot of binary compatibility issues and has been crucial to ensuring 2.9.x Scala releases are binary compatible. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;I'm trying to organize projects to help ensure *all* libraries for Scala can be released against all the major versions and remain binary compatible. &amp;nbsp;The story is changing, and has done so rapidly over the past two years. &lt;br /&gt;&lt;br /&gt;I'd love to see Lift, and others start adopting binary compatibility standards for there releases as well. &amp;nbsp; This is not just a scala-the-library or scala-the-langauge issue. &amp;nbsp; Libraries matter, just as they do in Java.&lt;br /&gt;&lt;br /&gt;So while David's post highlights an issue, my response is:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Help us (the Scala community) out! &amp;nbsp;We're going there, we're doing that.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-1099806865674280113?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/1099806865674280113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=1099806865674280113' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1099806865674280113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1099806865674280113'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/12/scala-fresh-is-alive.html' title='Scala Fresh is alive'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-6012403917379385031</id><published>2011-11-29T19:59:00.001-05:00</published><updated>2011-11-29T20:49:37.975-05:00</updated><title type='text'>Macro vs. Micro Optimisation</title><content type='html'>So there's recently been a bit of hype about another Colebourne article:&amp;nbsp;&lt;a href="http://blog.joda.org/2011/11/real-life-scala-feedback-from-yammer.html"&gt;http://blog.joda.org/2011/11/real-life-scala-feedback-from-yammer.html&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'd like to respond to a few points he makes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First - You should evaluate Scala and pay attention to its benefits and flaws before adopting it. &amp;nbsp;Yes, there are flaws to Scala. &amp;nbsp; Working at typesafe makes you more aware of some of them. &amp;nbsp;We're actively working to reduce/minimize/get rid of these. &amp;nbsp; In my opinion, the negatives of using Scala are peanuts compared to the postives of choosing Scala over Java. &amp;nbsp;I think everyone should make up their own mind about this. &amp;nbsp; Not everyone is going to choose Scala. &amp;nbsp;I feel bad for those who don't, but I make no effort to convince you further than showing you the &lt;a href="https://github.com/jsuereth"&gt;40+ Open source Scala projects&lt;/a&gt; I have on github. &amp;nbsp;It's a language with a lot to like and a bit to dislike.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, to the meat of what I want to say. &amp;nbsp; Don't get lost in micro&amp;nbsp;optimization&amp;nbsp;when discussing programming.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The blog article discusses writing high-performance code in the critical path that has crazy performance needs. &amp;nbsp; This is not your every day development. &amp;nbsp; Scala loses a lot of benefits in this world, because features like closures have overhead on the JVM. &amp;nbsp;Hopefully when Java adopts closures, this overhead can be alleviated, but it is there right now. &amp;nbsp; The set of rules from the email is known to a lot of us Scala devs when writing a performance intensive section of code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'll reiterate a few to agree with:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(1) Avoid closure overhead. &amp;nbsp; If you can't get the JVM to&amp;nbsp;optimize&amp;nbsp;away and need to allocate a closure constantly in a tight loop, this can slow down a critical section. &amp;nbsp;This is correlated with&lt;/div&gt;&lt;div&gt;(1a) Don't use a for loop. &amp;nbsp;For expressions (and loops) in Scala are implemented as closures. &amp;nbsp; There are &lt;a href="http://code.google.com/p/scalacl/"&gt;some efforts underway to *inline* these closures&lt;/a&gt; as an&amp;nbsp;optimization. &amp;nbsp;This performance hit isn't a&amp;nbsp;permanent&amp;nbsp;one. &amp;nbsp; As the compiler matures, you'll see a lot of&amp;nbsp;optimization&amp;nbsp;work happen. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(2) Use private[this] to avoid an additional method. &amp;nbsp; Scala generated methods and fields for val/var members. &amp;nbsp; Using private[this] informs the compiler that it can&amp;nbsp;optimize&amp;nbsp;away the method. &amp;nbsp; Again, while hotspot can&amp;nbsp;optimize&amp;nbsp;this away if you're in a very critical section, it may be a good idea to&amp;nbsp;optimize. &amp;nbsp; In fact, the whole promotion to fields and methods aspect of Scala classes deserves attention from anyone writing performance critical code. &amp;nbsp; The rules are also there in Java, it's just that you probably have people that already know them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(3) Avoid invokevirtual calls. &amp;nbsp;(Coda lists this as avoid Scala's collections). &amp;nbsp;The true issue here is that invoke-virtual can make a difference in performance critical sections of code. &amp;nbsp;Again, this is one I think we can improve with a few final declarations and maybe an annotation or two.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's the big *missing* point in all that feedback. &amp;nbsp; This is for performance critical sections of code, not for general purpose applications. &amp;nbsp; I think when it comes to performance bottlenecks, you need to pull out the stops and&amp;nbsp;optimize&amp;nbsp;the heck out of your apps. &amp;nbsp; Look at the &lt;a href="http://akka.io/"&gt;Akka&lt;/a&gt; framework from typesafe. Akka uses a lot of "dirty" scala code to&amp;nbsp;achieve&amp;nbsp;high non-blocking concurrent performance. &amp;nbsp;It's one of the most amazing libraries, and the code is pretty low level. &amp;nbsp; It also supports a very high level of abstraction when writing your application. &amp;nbsp; It uses PartialFunctions (which are sort of a combination of pattern matching and closures) and traits, both of which have some overhead. &amp;nbsp; However the resulting *application* is fast. &amp;nbsp;Why? &amp;nbsp; The inner loops are fast and&amp;nbsp;optimized&amp;nbsp;and the application *architecture* can be optimised. &amp;nbsp;In a high level language, you can take advantages of designs that you would *never* execute in a lower-level language because the code would be unmaintainable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You see, most of us like to be able to read and understand what our code does. &amp;nbsp; Scala has some features where you can write very expressive code in a few lines. &amp;nbsp; After getting over the initial hump, this code is pretty easy to maintain. &amp;nbsp; If I were to write that same code in Java, it would look odd, confusing as hell, and no one would want to maintain it. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I learned this lesson pretty hard core at Google.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Google has a pretty stringent C++/Java style guide. &amp;nbsp;One that is tuned for high performance servers. &amp;nbsp; The&lt;a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml"&gt; C++ style guide is public&lt;/a&gt;. &amp;nbsp;The style guide frowns on things like the use of 'smart' pointers that 'garbage collect' because you can't be sure that GC will happen at a critical moment in the code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Google also has a high performance Map-Reduce library. &amp;nbsp;This thing is pretty amazing, with all sorts of crazy cool features like joining data on the *map* part of the map-reduce. &amp;nbsp;The library followed all the google coding conventions and is generally held up as a piece of awesome software, which its.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, writing applications with the Map-Reduce library was less than idea. &amp;nbsp; I could write pretty clean code with the MR library. &amp;nbsp;My Mappers were pretty light weight and minimalistic. &amp;nbsp;Same with my reducers. &amp;nbsp; You'd then string together a series of map-reduces in this crazy guitar inspired "patch it together" configuration and the thing would be off to the races. &amp;nbsp;The downside is that the throughput of this kind of processes was *sub optimal*.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It wasn't anything inherent in the libraries. &amp;nbsp;The libraries were fast and good. &amp;nbsp;The APIs were optimised for high speed performance. &amp;nbsp;However, writing optimal *architectures* in the framework was tough. &amp;nbsp; If I wanted to do any crazy performance features, like combining map functions and reduce functions in a single map reduce run, the code got ugly *fast*. &amp;nbsp;Not only that, it was very difficult to maintain because of all the odd bookkeeping. &amp;nbsp;I have 10 outputs ordered by key, this is the one writing to that file right? &amp;nbsp;KRAP.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I spent 6 months writing applications of this nature and feeling like there had to be something better. &amp;nbsp; I started on a venture to write something, and as usual found that someone else already had. &amp;nbsp;That's when I found out about Flume and met Craig Chambers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;FlumeJava was a map reduce library that was gaining a lot of traction at Google, but I had heard a lot of complaints about its API. &amp;nbsp;Around the time I was looking at it, Flume C++ was coming into existence. &amp;nbsp;My team was one of the alpha users of the C++ variant.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The C++ API was a thing of beauty. &amp;nbsp; Like its Java cousin, it treats data a set of Parallel Distributed Collections. &amp;nbsp; You can see Daniel and my talk on the Scala equivalent &lt;a href="http://days2011.scala-lang.org/node/138/282"&gt;here&lt;/a&gt;. &amp;nbsp;Converting Mappers and Reducers into this API was pretty simple. &amp;nbsp;You could even do it directly by just annotating your Mappers and Reducers with types.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My team saw a 30-40% reduction in code size for some of our map-reduce pipelines. &amp;nbsp;We had an 80% reduction in code for unit tests (which was by far the most amazing benefit). &amp;nbsp; Not only that, the Flume library optimizes the pipeline by performing all sorts of dirty map-reduce tricks for you. &amp;nbsp;In some cases we dropped a map-reduce call or two. &amp;nbsp;In the worst case, we had the same number we had started with.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What was wrong with the library? &amp;nbsp;It violated *almost every* style rule for C++ at google. &amp;nbsp;That's right, smart pointers, classes with inline member definitions the works. &amp;nbsp; I loved every second of it. &amp;nbsp;Why? &amp;nbsp;Because I was getting stuff done *faster* than before with *less* code and the pipelines ran *faster*. &amp;nbsp; It was a crazy win.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The startup time might not have been as optimal as it could be. &amp;nbsp;Flume ran an on-the-fly&amp;nbsp;optimization&amp;nbsp;before running your pipeline. &amp;nbsp;That was being improved all the time with neat tricks. &amp;nbsp; Things I didn't have to write to watch my app speed up, both runtime and startup time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The key here is that the designers of Flume weren't focused on micro&amp;nbsp;optimization&amp;nbsp;but *macro*&amp;nbsp;optimization. &amp;nbsp;The inner guts of the library used the very fast and efficient Map-Reduce library and the wrappers they had were as efficient as they could make them. &amp;nbsp; My code did not have to follow these rules, because the core loops were fast. &amp;nbsp;When it came down to it, my code used high level concepts. &amp;nbsp; Something akin to a closure and for-expressions in Scala (Note: The Scala equivalent *did* use for-expressions and closures with no&amp;nbsp;noticeable&amp;nbsp;performance hit).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are times when writing Scala code requires care and&amp;nbsp;optimization&amp;nbsp;in the micro level. &amp;nbsp;However, don't lose the forest for the trees. &amp;nbsp;Think about the entire application architecture. &amp;nbsp;Scala will open up&amp;nbsp;possibilities&amp;nbsp;for writing code that you'd never dream of trying to maintain in C++ or Java. &amp;nbsp;Take Akka as a shining example.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And when you need the performance, listen to those techniques. &amp;nbsp; Viktor Klang can probably give you a *ton*more. &amp;nbsp;I know I learn more every time I talk with him.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6012403917379385031?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6012403917379385031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6012403917379385031' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6012403917379385031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6012403917379385031'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/11/macro-vs-micro-optimisation.html' title='Macro vs. Micro Optimisation'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-8005338058990350909</id><published>2011-09-16T12:44:00.000-04:00</published><updated>2011-09-16T13:36:16.970-04:00</updated><title type='text'>SBT and Plugin design</title><content type='html'>Sbt 0.10 brings *a lot* of power to the table. &amp;nbsp; SBT 0.10 switched from a class/inheritance based build system into a more functional approach. &amp;nbsp; For those who aren't familiar, here's the quick spiel on SBT.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Basics of SBT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In SBT, a project is composed of &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Setting[_]&lt;/span&gt; values. &amp;nbsp;A Setting is sort-of a name-value pair &lt;i&gt;(more of a name *computation* pair)&lt;/i&gt;. &amp;nbsp;In the SBT command-line you can type the name of a setting and get its value (or computed value). &amp;nbsp; For example, &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;test&lt;/span&gt; is a task in SBT that you can type in the command line. &amp;nbsp; The setting's computation is executed and the value returned. &amp;nbsp; This setting may depend on other settings for its value.&lt;br /&gt;&lt;br /&gt;SBT provides a simple way to construct a project. &amp;nbsp; In the root directory, any *.sbt file is compiled to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Setting[_]&lt;/span&gt; values. &amp;nbsp; A &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Setting[_]&lt;/span&gt; is two things: &amp;nbsp; A name &lt;i&gt;(Key + Scope)&lt;/i&gt; and a Value &lt;i&gt;(or computation, called &lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Initialize&lt;/span&gt;&lt;i&gt; in SBT)&lt;/i&gt;. &amp;nbsp;One can construct a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Setting[_]&lt;/span&gt; via the SBT dsl:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;sourceDirectory in Compile &amp;lt;&amp;lt;= baseDirectory apply { dir =&amp;gt;&lt;br /&gt;  dir / "src" / "main" / "scala"&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In this example, the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sourceDirectory&lt;/span&gt; Key (name) is assigned an &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Initailzation&lt;/span&gt; (value/computation). &amp;nbsp;The &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;&amp;lt;=&lt;/span&gt; operator is used to construct a Setting[_] by joining a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Key&lt;/span&gt; and an &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Initialiation&lt;/span&gt;. &amp;nbsp;In the above example, the Initialization is constructed to pull the current value of the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;baseDirectory&lt;/span&gt; key and modify it for the value of the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sourceDirectory&lt;/span&gt; key. &lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note:&lt;/i&gt; The &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;apply&lt;/span&gt; method is used on &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;baseDirectory&lt;/span&gt; because both &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;baseDirectory&lt;/span&gt; and sourceDirectory are &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;SettingKey[_]&lt;/span&gt;s. &amp;nbsp;SBT distinguishes between three types of &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Setting[_]&lt;/span&gt; values: &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Setting&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Task&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;InputTask &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;with corresponding&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; SettingKey&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;,&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; TaskKey &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;and&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; InputKey &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;"name" types. &amp;nbsp;The three are distinguished as follows:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;SettingKey&lt;/b&gt; - Something that is computed *once* on project load (or reload). like a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;val&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;TaskKey&lt;/b&gt; - Something that is computed each time it is called, like a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;def&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;InputKey&lt;/b&gt; - Something that takes user input to perform its task.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Configurations&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;SBT uses a &lt;i&gt;configuration matrix&lt;/i&gt; to define the same task against different configurations. &amp;nbsp; For example, SBT defines a task for compiling Scala code called &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;compile&lt;/span&gt;. &amp;nbsp;This mechanism has a bunch of required settings. &amp;nbsp; However, it wouldn't be DRY to repeat all these settings for compiling &lt;i&gt;*test*&lt;/i&gt; code as well. &amp;nbsp;So instead, SBT defines the &lt;i&gt;*same*&lt;/i&gt; settings in two different configurations, on called &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Test&lt;/span&gt; and another called &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Compile&lt;/span&gt;. &amp;nbsp;To compile just tests in SBT, you can prefix a task with its configuration, e.g. &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;test:compile&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Plugin Design&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what does this have to do with plugin design? &amp;nbsp;SBT plugins need to integrate &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Setting[_]&lt;/span&gt; values into a build without conflicting with SBT default settings and other plugins. &amp;nbsp;To complicate matters, SBT imports all the members of plugin classes into scope of a project using a wildcard import. &amp;nbsp; This means all the plugins you use could have conflicting names that step on each other. &amp;nbsp; Combined with potentially conflicting key names, plugins need to be very careful with how they define things.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having worked on several plugins recently, I'd like to outline a strategy that I think achieves a certain elegance in definition and usage, as well as the safety one wants from a plugin.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The basic pattern is as follows. &amp;nbsp; Define an object with the name you want for your plugin *inside* the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Plugin&lt;/span&gt; class. &amp;nbsp; For example, if I want a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;xsbt-suereth-plugin&lt;/span&gt;, I would define the following:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="code"&gt;&lt;pre&gt;import sbt._&lt;br /&gt;import Keys._&lt;br /&gt;&lt;br /&gt;object SbtSuerethPlugin extends Plugin {&lt;br /&gt;&lt;br /&gt;  object suereth {&lt;br /&gt;     // Your code here&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Inside of the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;suereth&lt;/span&gt; object I hide all my definitions and code. &amp;nbsp; This isolates my plugin from other sbt plugins, as long as no one names their methods "&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;suereth&lt;/span&gt;".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, let's define a new &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Config&lt;/span&gt; object that we can use to protect our keys from other plugins.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;  object suereth {&lt;br /&gt;     val Config = config("suereth")&lt;br /&gt;     // Your settings here&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Config&lt;/span&gt; also shares the name of the plugin, so in the command line tasks and settings can be run using &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;suereth:&amp;lt;your-task-here&amp;gt;&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;The next step is define whatever custom keys your plugin will use. &amp;nbsp;Let's create a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;blog&lt;/span&gt; key.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;  object suereth {&lt;br /&gt;     ...&lt;br /&gt;     val blog = SettingKey[String]("blog", "location of the blag") in Config&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The key is automatically placed into the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;suereth&lt;/span&gt; configuration using the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;in&lt;/span&gt; method. &amp;nbsp;This has two benefits:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;When defining the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Initialization&lt;/span&gt; for a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Setting[_]&lt;/span&gt;, there's no need to continue writing &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;blog in Config&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Users&lt;/i&gt; of the plugin can directly access &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;suereth.blog&lt;/span&gt; without needing to specify &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;suereth.blog in suereth.Config&lt;/span&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Note: &amp;nbsp;You can also reference SBT keys in your configuration by writing:&lt;/i&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;val sources = Keys.sources in Config&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Finally, we can provide default values/computations for tasks and settings in our plugin. &amp;nbsp; By convention, calling these &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;settings&lt;/span&gt; is a good idea.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;  object suereth {&lt;br /&gt;     ...&lt;br /&gt;     lazy val settings: Seq[Setting[_]] = Seq(&lt;br /&gt;        blog := "http://suereth.blogspot.com"&lt;br /&gt;     )&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Notice how the keys are access directly but are actually in the appropriate config matrix. &amp;nbsp; This helps defining your plugin source code, but will also help users of your plugin. &amp;nbsp; Let's look at what a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;build.sbt&lt;/span&gt; file will be for this plugin.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;seq(suereth.settings:_*)&lt;br /&gt;&lt;br /&gt;suereth.blog := "http://blog.typesafe.com"&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Notice how the settings for this plugin are completely namespaced by the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;suereth&lt;/span&gt; object. &amp;nbsp; We've tied the concept of a "configuration" &amp;nbsp;axis for keys with accessing values in an object. &lt;br /&gt;&lt;br /&gt;I find this mechanism of defining plugins both helpful from a development perspective and a user perspective. &amp;nbsp; Curious to hear what others think.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-8005338058990350909?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/8005338058990350909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=8005338058990350909' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8005338058990350909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8005338058990350909'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/09/sbt-and-plugin-design.html' title='SBT and Plugin design'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-5375598846112077221</id><published>2011-07-22T15:46:00.001-04:00</published><updated>2011-07-22T21:11:37.763-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='typesafe'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Leaving Google for Typesafe</title><content type='html'>So, as some of you may have found out already, I'll be leaving Google effective July 22nd and moving to a new role at &lt;a href="http://www.typesafe.com/"&gt;Typesafe&lt;/a&gt;.  Some of you may be wondering why, so I'm offering my reasons in a blog post for the curious:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Scala has been gaining lots of traction in the market space recently.  I think Scala is  and has been reaching its tipping point.   I'm hoping to contribute everything I can to sure it remains a viable language for everyday development.&lt;/li&gt;&lt;li&gt;While Google does have 20%time to work on individual projects, this correlated to about a day a week to work on all things Scala within Google.  Rare was the opportunity to do anything significant or to contribute back to the community, due to time constraints.  While I was able to accomplish one &lt;a href="http://twitter.com/#!/odersky/status/76713658922696704"&gt;pretty good&lt;/a&gt; &lt;a href="http://days2011.scala-lang.org/node/251"&gt;thing&lt;/a&gt;, aligning my work with my passions seemed like the best thing to do.&lt;/li&gt;&lt;li&gt;It's part of a new weight loss program called "pay for your own food".   This was tempered by my wife's purchase of a new grill for my birthday, which has seen heavy use in the past few weeks.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So, while I see Scala's future as bright and rosy and I can't explain how excited I am to start at typesafe, I'd also like to do a little reflection on Google and some of what makes it a great company.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Google cares about employees&lt;/b&gt;&lt;br /&gt;This is not a lie.   Google, as best as it can, tries to mean what it says.   At my previous companies you'd hear "I'd love to do this, but my hands are tied".   At Google, you often hear "I don't know, but let's ask someone who does" which usually turns into "Yes, go ahead".  It was rare that something I asked for was denied.   My *perception* of what was acceptible is an entirely different thing.   At Google, there are people who think what you think (at over 10k engineers, it's guaranteed one will probably agree with you about something), and that engineer might have also tried to accomplish the same task as you.   Go ask about it and find like-minded individuals.   You'll be surprised how much Google tries to do what they say.&lt;br /&gt;The other side to this coin is that the *corporate entity* and by that I mean the higher ups like to do things for all Google employees.   Like bonuses.  They really do happen, and they really do try to treat you like a human being.&lt;br /&gt;&lt;br /&gt;The other side to this coin is the interview process.   I've seen so many negative posting about the interview process.   Well, I'm here to dispell a few of those.   Google's interviews will challenge your technical abilities.   If this annoys you and you don't take the job, then good.  You're probably not the type to &lt;strike&gt;herd cats&lt;/strike&gt; deal with politics/relationships involves with a large developer base.   If you can't cut the interview, then it gives you a reason to go back and practice.   However, more importantly, Google would rather turn away a good candidate than hire a bad one.   This mindset is very impressive.   It really makes a huge difference on the ability of teams to accomplish things.   I knew every employee I worked with at google was reliable to get work done, not something that's always the case externally.&lt;br /&gt;In the future I know my interview style will change.  No more will interviewees be allowed to just talk about experiences without showing some code.  It's amazing some of the depths you can learn here.   It's even great when an interviewee fails to answer the question correctly because you *learn their thought process*.   I know for me, a few candidates who struggled were the ones I wanted sitting beside me coding, more so than the ones who blazed through a question but had a more 'better than thou' aura.&lt;br /&gt;So, the point here is care about your employees and care about who you hire.   Your company will be in far better shape if you do this.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt; Culture is faster than process&lt;/b&gt;&lt;br /&gt;Google tries to instill a culture of 'doing the right thing' its employees, rather than outlining software process to a T.  There are a few 'inconveniences' that exist, but other than mandatory code reviews, a lot of the process is up to the team to do what's best.   The other side to this coin is the corporate culture tries to help define and change what's best.   It's amazing how one executive making a statement in an all hands meeting can suddenly alter the perceived "best way to code" and get the company to move.   It's also surprisingly hard to change culture once it has been really embedded into the engineers, which is the danger.   A sense of 'right' in the ways of writing software can be beneficial, but can also turn into anti-patterns if not tempered.   I'd love to go into more details here, just feel free to bug me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-5375598846112077221?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/5375598846112077221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=5375598846112077221' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5375598846112077221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5375598846112077221'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/07/leaving-google-for-typesafe.html' title='Leaving Google for Typesafe'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-2976466964557979527</id><published>2011-06-16T23:41:00.002-04:00</published><updated>2011-06-17T08:19:39.421-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='collections'/><category scheme='http://www.blogger.com/atom/ns#' term='generics.'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>A Generic Quicksort in Scala</title><content type='html'>So, I decided to create a quicksort algorithm in Scala that showcases how to write 'generic' collection methods.   That is, how can we write an external method that works across many types of collections *and* preserves the final type.&lt;br /&gt;&lt;br /&gt;Well, here's how you do it:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;import scala.collection.SeqLike&lt;br /&gt;import scala.collection.generic.CanBuildFrom&lt;br /&gt;import scala.math.Ordering&lt;br /&gt;&lt;br /&gt;object QuickSort {&lt;br /&gt;  def sort[T, Coll](a: Coll)(implicit ev0 : Coll &amp;lt;:&amp;lt; SeqLike[T, Coll],&lt;br /&gt;                             cbf : CanBuildFrom[Coll, T, Coll],&lt;br /&gt;                             n : Ordering[T]) : Coll = {&lt;br /&gt;    import n._&lt;br /&gt;    if (a.length &amp;lt; 2)&lt;br /&gt;      a&lt;br /&gt;    else {&lt;br /&gt;      // We pick the first value for the pivot.&lt;br /&gt;      val pivot = a.head&lt;br /&gt;      val (lower : Coll, tmp : Coll) = a.partition(_ &amp;lt; pivot)&lt;br /&gt;      val (upper : Coll, same : Coll) = tmp.partition(_ &amp;gt; pivot)&lt;br /&gt;      val b = cbf()&lt;br /&gt;      b.sizeHint(a.length)&lt;br /&gt;      b ++= sort[T,Coll](lower)&lt;br /&gt;      b ++= same&lt;br /&gt;      b ++= sort[T,Coll](upper)&lt;br /&gt;      b.result&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I've chosen a somewhat imperative approach to the problem.   The quick sort algorithm is split into two parts:  The first checks for small collections and returns them, the second picks a pivot and decomposes the collection into three pieces.   Theses pieces are sorted (if necessary) and pushed into a builder, cleverly named "b".   This "b" is given a hint to expect the entire collection to eventually wind up in the built collection (hopefully this helps performance).   Finally, after passing the three partitions to the builder, the result is returned.   &lt;br /&gt;&lt;br /&gt;The magic here is in the rather confusing type signature:&lt;br /&gt;&lt;pre&gt;def sort[T, Coll](a: Coll)(implicit ev0 : Coll &amp;lt;:&amp;lt; SeqLike[T, Coll],&lt;br /&gt;                             cbf : CanBuildFrom[Coll, T, Coll],&lt;br /&gt;                             n : Ordering[T]) : Coll&lt;/pre&gt;&lt;br /&gt;Let's decompose this a bit.  T is the type parameter representing elements of the collection.   T is required to have an Ordering in this method (the implicit n : Ordering[T] parameter in the second parameter list).    The ordering members are imported on the first line of the method.  This allows the &amp;lt; and &amp;gt; operations to be 'pimped' onto the type T for convenience.&lt;br /&gt;&lt;br /&gt;The second Type parameters is Coll.   This is the concrete Collection type.   Notice that *no type bounds are defined*.   It's a common habit for folks new to Scala to define generic collection parameters as follows:   Col[T] &amp;lt;: Seq[T].   Don't.   This type does not quite mean what you want.   Instead of allowing any subtype of sequence, it only allows subtypes of sequence that *also* have type parameters (which of course, is most collections).   Where you can run into issues is if your collection has (a) no type parameters or (b) more than one type parameter.   For example:&lt;br /&gt;&lt;pre&gt;object Foo extends Seq[Int] {...}&lt;br /&gt;trait DatabaseResultSetWalker[T, DbType] extends Seq[T] {...}&lt;/pre&gt;&lt;br /&gt;Both of these will fail type checkking when trying to pass them into a method taking Col[T] &amp;gt;: Seq[T].  &lt;br /&gt;&lt;br /&gt;To get the compiler to infer the type parameter on the lower bound, we have to defer the type inferencer long enough for it to figure this out.   To do that, we don't enforce the type constrait until implicit lookup using the &amp;gt;:&amp;gt; class.&lt;br /&gt;&lt;br /&gt;The type parameter: &lt;br /&gt;&lt;pre&gt;Coll &amp;lt;:&amp;lt; SeqLike[T, Coll] &lt;/pre&gt;Ensures that the type Coll is a valid Seq[T].   You may be asking why this signature uses SeqLike rather than Seq.&lt;br /&gt;&lt;br /&gt;GOOD QUESTION!&lt;br /&gt;&lt;br /&gt;SeqLike differs from Seq in that it *retains the most specific type of the sequence*.   This one of the magic tricks behind Scala's collections always returning the most specific type known.   That type is embedded in SeqLike.   To ensure that we can return the most sepcific type, we can Capture Coll as a SeqLike with Coll as the specific type.  This means that filters, maps, flatMaps, partitions should all try to preserve the type Coll.&lt;br /&gt;&lt;br /&gt;The last implicit parameter is the cbf CanBuildFrom.   Because we don't know how to construct instances of type Coll (because we don't know the type Coll at all), we need to implicitly receive evidence for how to construct a new Coll with sorted data.  &lt;br /&gt;&lt;br /&gt;Let's look at the result:&lt;br /&gt;&lt;pre&gt;scala&amp;gt; QuickSort.sort(Vector(56,1,1,8,9,10,4,5,6,7,8))&lt;br /&gt;res0: scala.collection.immutable.Vector[Int] = Vector(1, 1, 4, 5, 6, 7, 8, 8, 9, 10, 56)&lt;br /&gt;&lt;br /&gt;scala&amp;gt; QuickSort.sort(collection.mutable.ArrayBuffer(56,1,1,8,9,10,4,5,6,7,8))&lt;br /&gt;res1: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 1, 4, 5, 6, 7, 8, 8, 9, 10, 56)&lt;br /&gt;&lt;br /&gt;scala&amp;gt; QuickSort.sort(List(56,1,1,8,9,10,4,5,6,7,8))&lt;br /&gt;res18: List[Int] = List(1, 1, 4, 5, 6, 7, 8, 8, 9, 10, 56)&lt;br /&gt;&lt;br /&gt;scala&amp;gt; QuickSort.sort(Seq(56,1,1,8,9,10,4,5,6,7,8))&lt;br /&gt;res: Seq[Int] = List(1, 1, 4, 5, 6, 7, 8, 8, 9, 10, 56)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You may be asking why I've chosen Seq instead of GenSeq or GenTraversable or even GenIterable.  No particular reason, besides I wanted a reasonable assurance that the collection author expects the .length and indexed access methods to be called.&lt;br /&gt;&lt;br /&gt;So, what are the lessons to be learned here?&lt;br /&gt;&lt;br /&gt;(1) Use *Like subclasses to preserve the specific collection type&lt;br /&gt;(2) Defer inference using &amp;lt;:&amp;lt; to give the type checker a hope of succeeding&lt;br /&gt;(3) Provide @usecase comments for scaladoc so users won't get distracted by typesafe details.&lt;br /&gt;&lt;br /&gt;At lest, IMHO, this is the current way of creating generic collection code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-2976466964557979527?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/2976466964557979527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=2976466964557979527' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2976466964557979527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2976466964557979527'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/06/generic-quicksort-in-scala.html' title='A Generic Quicksort in Scala'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-8972713728130243683</id><published>2011-06-12T00:48:00.000-04:00</published><updated>2011-06-12T00:48:04.193-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='podcast'/><category scheme='http://www.blogger.com/atom/ns#' term='scalatypes'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scalatypes Podcasting Starting!</title><content type='html'>Well, Daniel, Yuvi and I started podcasting interviews and discussions on Scala.   Here's the first interview with Paul Phillips.   We have a *lot* more content to publish, but mastering audio still takes a backseat to day jobs and writing Scala in Depth.    Let us know what you think!&lt;br /&gt;&lt;br /&gt;&lt;script type="text/javascript" src="http://player.wizzard.tv/player/o/j/x/130785390929/config/k-ced60fc1953fa08d/uuid/root/height/360/width/640/episode/k-24dbe4d7163afc87.m4v"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-8972713728130243683?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/8972713728130243683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=8972713728130243683' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8972713728130243683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8972713728130243683'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/06/scalatypes-podcasting-starting.html' title='Scalatypes Podcasting Starting!'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-6780024517347454211</id><published>2011-06-03T16:48:00.002-04:00</published><updated>2011-06-03T16:48:41.758-04:00</updated><title type='text'>Scaladays 2011 Talk: Parallel Distributed Collections API</title><content type='html'>&lt;iframe src="https://docs.google.com/present/embed?id=dfqn4jb_110dngxgpg3" frameborder="0" width="410" height="342"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6780024517347454211?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6780024517347454211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6780024517347454211' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6780024517347454211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6780024517347454211'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/06/scaladays-2011-talk-parallel.html' title='Scaladays 2011 Talk: Parallel Distributed Collections API'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-6124293139825968692</id><published>2011-03-15T23:39:00.000-04:00</published><updated>2011-03-15T23:39:03.045-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='implicitNotFound'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Annotate your type classes (@implicitNotFound)</title><content type='html'>This is a real quick post saying that as of 2.8.1, everyone should be annotating their type class traits for better error messages.   Obviously, those of us who are supporting 2.8.0 or earlier are left out.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's an example REPL session:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Welcome to Scala version 2.9.0.r24384-b20110305105029 (OpenJDK 64-Bit Server VM, Java 1.6.0_20).&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&amp;gt; import annotation.implicitNotFound&lt;br /&gt;import annotation.implicitNotFound&lt;br /&gt;&lt;br /&gt;scala&amp;gt; @implicitNotFound(msg = "Cannot find Serializable type class for ${T}") trait Serializable[T]&lt;br /&gt;defined trait Serializable&lt;br /&gt;&lt;br /&gt;scala&amp;gt; def foo[X : Serializable](x : X) = x&lt;br /&gt;foo: [X](x: X)(implicit evidence$1: Serializable[X])X&lt;br /&gt;&lt;br /&gt;scala&amp;gt; foo(5)&lt;br /&gt;&lt;console&gt;:11: error: Cannot find Serializable type class for Int&lt;br /&gt;       foo(5)&lt;br /&gt;          ^&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The annotation has very little documentation, but apparently supports ${TypeName} templates to inject the names of types the compiler is looking for.   I believe you can also use this implicit on types with no type parameters.&lt;br /&gt;&lt;br /&gt;Happy hacking everyone!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6124293139825968692?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6124293139825968692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6124293139825968692' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6124293139825968692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6124293139825968692'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/03/annotate-your-type-classes.html' title='Annotate your type classes (@implicitNotFound)'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-2209362938951224717</id><published>2011-02-18T11:40:00.002-05:00</published><updated>2011-02-18T11:40:32.018-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='implicits'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Slides for today's NEScala talk</title><content type='html'>Here's the slides for todays talk for those who wish to follow along on their laptops.&lt;br /&gt;&lt;iframe src="https://docs.google.com/present/embed?id=dfqn4jb_106hq4mvbd8&amp;size=m" frameborder="0" width="555" height="451"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-2209362938951224717?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/2209362938951224717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=2209362938951224717' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2209362938951224717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2209362938951224717'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2011/02/slides-for-todays-nescala-talk.html' title='Slides for today&apos;s NEScala talk'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-6355641187852265991</id><published>2010-10-15T22:49:00.001-04:00</published><updated>2010-10-16T09:27:40.655-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='composition'/><category scheme='http://www.blogger.com/atom/ns#' term='type traits'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>On Macro-Composition vs. Micro-Composition and Social software development.</title><content type='html'>I was talking to a co-worker today about using C++ templates to compose functionality in objects.  I also mentioned how you can encode type traits using templates.  My Coworker, conveniently aliased as "Bob", asked why you would want to use type traits rather than defining an interface directly and wrapper objects.&lt;br /&gt;&lt;br /&gt;In response, I gave rather lame answers, which I intend to amend here.   The basic gist is that I feel a lot of Object Oriented languages don't pay enough attention to macro composition of components in a system.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;First, I'd like to state that In a lot of my code, there are a set of classes that define the format of data, or the "data layer".   This layer has a certain "mind-share" around it.   It is "owned" be a group of individuals and the portion of code they own.   This data is passed around to other teams of people.   &lt;br /&gt;&lt;br /&gt;Note that I specifically state "other teams" and not "other components".  In a lot of software shops, we think of software being comprised of sub-components of a system, but I tend to find that the sub-components of a system are also defined by the teams that work on them.  If a particular team works on several sub-components, these components tend to be cohesive and reuse a lot of code.   The boundaries between these teams are important to pay attention to.&lt;br /&gt;&lt;br /&gt;It's the boundaries where we tend to do a lot of conversions from one data definition to another.   Each team wants to wrap its own "needs" around the ontology of classes.   So in an OO system, this usually means wrapping data from one set of classes to another, or bunch of external methods that manipulate the data from another team.   Because of this natural bent in programming, it's sometimes necessary to be able to adapt other people's specific classes into your own ontology.   This is where type classes come in.&lt;br /&gt;&lt;br /&gt;I've blogged about type classes/type traits before, so I won't bore you again.   The basic gist of the idea is to define an interface for your method.   For example, I'm writing something that works with tree-like data structures where each parent node could have multiple children.   I define a type trait as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;trait TreeLike[NodeType] {&lt;br /&gt;     def isParent(node : NodeType) : Boolean&lt;br /&gt;     def children(node : NodeType) : Iterator[NodeType]&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This allows me to take any "node" type and traverse it.   Now, Let's write an algorithm where we want to see if a condition holds true down one "branch" of the tree to a leaf for every Node of this path.   We can use our TreeLike type trait.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;final def hasValidDepthPath[T : TreeLike](node : T, validator : T =&gt; Boolean) : Boolean =&lt;br /&gt;  if(validator(node)) {&lt;br /&gt;    val helper = implicitly[TreeLike[T]]&lt;br /&gt;    !helper.isParent(node) || helper.children(node).exists(hasValidDepth(_, validator))&lt;br /&gt;  } else false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The hasValidDepthPath method uses the TreeLike type trait rather than a different class.   This lets us use non-treelike structures as trees.   For example, we can turn a list into a tree where each branch is the same list but missing one item of the index.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;scala&gt; def dropIndex(x : List[Int], idx : Int) = x.zipWithIndex.filter(_._1 != idx).map(_._2) &lt;br /&gt;dropIndex: (x: List[Int],idx: Int)List[Int]&lt;br /&gt;&lt;br /&gt;scala&gt; dropIndex((1 to 10).toList, 2)&lt;br /&gt;res2: List[Int] = List(0, 2, 3, 4, 5, 6, 7, 8, 9)&lt;br /&gt;&lt;br /&gt;implicit val decomposeList[T] = new List[T] {&lt;br /&gt;  def isParent(node : List[T]) = node.length != 1&lt;br /&gt;  def children(node : List[T]) = (1 to node.length).map(dropIndex(node, _))&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now we can use a List of items as an input to our hasValidDepthPath method.  &lt;br /&gt;&lt;br /&gt;Now to my coworkers question:  Why would I want to add this extra layer?&lt;br /&gt;&lt;br /&gt;My answer is that it helps when working with "ontologies" from different teams.   That is, each team has their own way of describing data.   This mechanism allows our functions to mostly ubiquitously deal with these differing items, writing adapters for each ontology.   This makes more sense when your algorithms deal with many different input types.   In fact, I think it makes the most sense for 'peripheral' code.   That is code that interacts with other teams.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, for the second part of the rant.&lt;br /&gt;&lt;br /&gt;I feel a lot of languages don't support macrocomposition well.   A great example of this is the existence of the Spring Framework.   Spring allows you to define interfaces, objects and their dependent components.   You can then build configurations where you create specific objects, bind them to names and inject them into other objects.   You are essentially defining the components of your system at a micro-&gt;macro level.   Spring configuration allows you to focus on building the various components as needed at an object-by-object level until you are configuring objects that comprise major subcomponents of your system.  Google Guice allows you do to a similar thing in Java using annotations.&lt;br /&gt;&lt;br /&gt;The important thing here, IMO is that there is a distinction between defining components/classes and composing them.   We define a component that uses others via some interface in one section, and we combine these components together in another.&lt;br /&gt;&lt;br /&gt;In C++ we can also accomplish this to some extent using type traits.   In C++ type traits usually take the form as templated structures.   Composition is then done using template arguments.   The best example of this is the STL and its usage of traits for allocation, comparison, hashing, etc.&lt;br /&gt;&lt;br /&gt;In C++, we could define a service as follows&lt;br /&gt;&lt;pre class="brush:cpp"&gt;template&amp;lt;typename Logger, typename Threading&amp;gt;&lt;br /&gt;class Service {&lt;br /&gt; public:&lt;br /&gt;   typename Threading::ScopeLock ScopeLock;&lt;br /&gt;   void MyMethod() {&lt;br /&gt;     Logger log;&lt;br /&gt;     Threading threading;&lt;br /&gt;     {&lt;br /&gt;       ScopeLock scoped(mutex_);&lt;br /&gt;       log.info("OMG!!!");&lt;br /&gt;     } &lt;br /&gt;  }&lt;br /&gt; protected:&lt;br /&gt;   typename Threading::Mutex mutex_;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This service is really really simple, but shows how to compose with type traits.   The Threading interface is any class that defines a Mutex typedef (for mutexes), a ScopeLock typedef (for locking mutexes within a scope).   This class could be reused across various threading libraries, by providing something with the correct type definitions.   I would expect to see, somewhere else in code, the following "Compositional" Code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:cpp"&gt;// This code replaces a Spring XML configuration.&lt;br /&gt;typedef Service&amp;lt;PthreadThreading, DefaultLogging&amp;gt; MyService;&lt;br /&gt;typedef SomeHigherLevelService&amp;lt;...., MyService&amp;gt; MyHigherLevelService;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The nice aspect here is that I can use typedefs to compose "micro" components of my system and aggregate those into "macro" components.   It's the same technique used for both.&lt;br /&gt;&lt;br /&gt;In Scala, I've used the following tactic:   Define a trait which implies composition.   This method has a lot of boilerplate, so bear with me.&lt;br /&gt;&lt;br /&gt;I want to define a Logger service that traits can use.  To do this I define the generic Logger trait and a generic HasLogger trait.&lt;br /&gt;&lt;pre class="brush:scala"&gt;trait SimpleLogger {&lt;br /&gt;  def info(msg : String) : Unit&lt;br /&gt;  def warn(msg : String) : Unit&lt;br /&gt;  def fatal(msg : String) : Unit&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;trait HasSimpleLogger {&lt;br /&gt;  val logger : SimpleLogger&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This SimpleLogger provides no advanced features, just three levels of logging.   The HasSimpleLogger trait defined an abstract value for the Logger.   It does not instantiate the logger, it merely denotes that a class will have one (i.e. needs to be composed with one).    Later, we will define some service:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;trait MyService extends HasSimpleLogger {&lt;br /&gt;  def serviceMethod() {&lt;br /&gt;    logger.info("MyService: Someone called my method")&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is how we define each "abstract" component.   We extend each composition trait (i.e. HasFoo) and then utilize the components as necessary.   Again, there will be code somewhere that composes these components together.   In Scala, the mechanism of composition is the trait *not* a class instance:&lt;br /&gt;&lt;br /&gt;&lt;pre class="bursh:scala"&gt;trait MyComposedService extends MyService with HasDefaultLoggerImplementation&lt;br /&gt;&lt;br /&gt;trait HasMyComposedService extends HasMyService {&lt;br /&gt;  val mySerivce = new MyComposedService {}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Why do we have to compose in this manner?   Because we'd like to have more control when composing large systems together.   This mechanism allows us to "reconfigure" a MyComposedService with additional behavior or alternative subcomponents without having to redeclare *all* the subcomponents.&lt;br /&gt;&lt;br /&gt;The downside to this approach is that it is full of boilerplate.   However, notice again the distinction between defining components and aggregating behavior into our final system.&lt;br /&gt;&lt;br /&gt;I'm of the opinion that these two functions are key to creating reusable software and they need to be simple and elegant to be used.   I've yet to see a large system where I felt the composability ever reached the ideals touted by J2EE of old.  In fact, I feel EJBs are horrible for microcomposition.   The Spring framework further proved this by provided a microcomposition layer below Session beans that became quite popular.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In any case, these are my ramblings and musings on development.   I'd love to hear back from you.   I'm of the opinion that after becoming a proficient software developer, the solutions I write solve three issues:&lt;br /&gt;&lt;br /&gt;(1) A complex new algorithm to solve a problem "never before solved" (at least by the company I work for), or some foundational library.&lt;br /&gt;(2) Munging data between social components of software, or differing ontologies&lt;br /&gt;(3) Composing components to form a complex system.&lt;br /&gt;&lt;br /&gt;I feel a lot of languages focus on (1).   The languages I tend to prefer allow me to do (2) and (3) with ease.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6355641187852265991?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6355641187852265991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6355641187852265991' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6355641187852265991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6355641187852265991'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/10/on-macro-composition-vs-micro.html' title='On Macro-Composition vs. Micro-Composition and Social software development.'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-5759189149355697352</id><published>2010-08-17T22:41:00.000-04:00</published><updated>2010-08-17T22:41:09.341-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jigasw'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>What's the state of Jigsaw?</title><content type='html'>I hadn't been paying close attention, but recently &lt;a href="http://mail.openjdk.java.net/pipermail/jigsaw-dev/2010-August/001105.html"&gt;a few emails questioning the future of the jigsaw project&lt;/a&gt; have been sent to the jigsaw-dev mailing list.  The last check-in posted to the mailing list was on June 8th, and was the tail-end of a flurry of check-ins from the jigsaw team.&lt;br /&gt;&lt;br /&gt;The whole thing is rather curious, but without any specific word from Oracle, it's all speculation.   I have my own guesses, but it's probably best I keep those to myself for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-5759189149355697352?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/5759189149355697352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=5759189149355697352' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5759189149355697352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5759189149355697352'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/08/whats-state-of-jigsaw.html' title='What&apos;s the state of Jigsaw?'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-1417374922965175779</id><published>2010-07-13T00:17:00.000-04:00</published><updated>2010-07-13T00:17:09.804-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monkey patching'/><category scheme='http://www.blogger.com/atom/ns#' term='type classes'/><category scheme='http://www.blogger.com/atom/ns#' term='duck typing'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Monkey Patching, Duck Typing and Type Classes</title><content type='html'>Somewhat recently, there have been a bunch of articles written about Scala and how you can create something that looks like Haskell's type class feature.  I'm not going to duplicate these posts, but I am going to go beyond just the mechanics of creating a type class and discuss how to utilise some of Scala's advanced features with type classes to create some pretty robust code.   A lot of the post borrows ideas from my upcoming book, Scala In Depth.   The examples come from the &lt;a href="http://github.com/jsuereth/scala-arm"&gt;Scala ARM library&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;First off, let's assume you haven't read anything at all about Scala's type classes, but you do have a Ruby background.   In Ruby, you really loved duck typing.   It's the best.  I can just use methods and pass objects around and things work.   If a class doesn't have a method I need, I can either rely on some method missing magic, or just monkey patch it.  To those who don't know Ruby, monkey patching is the ability to add a method to an existing class on the fly.&lt;br /&gt;&lt;br /&gt;What if I told you that in Scala, for a small penalty, you could create methods that are flexible, like duck typed methods, and 100% compile-time type safe.   Not only that, you're also able to monkey-patch types as needed.   Don't believe me?  Let's look at some of the fun in the Scala ARM library.&lt;br /&gt;&lt;br /&gt;The motivation behind the ARM library is to create a flexible, robust (from exceptions) and simple-to-use automated-resource-management library that can greatly simplify things like JDBC or I/O in Scala.   The standard introduction to ARM in Scala is the withResource method outlined below.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;def withResource[A &lt;: { def close() }, B](resource : =&gt; A)(f : A =&gt; B) = {&lt;br /&gt;  val r = resource&lt;br /&gt;  try {&lt;br /&gt;    f(r)&lt;br /&gt;  } finally {&lt;br /&gt;    r.close()&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The with resource method takes a by-name argument that returns an opened resource, and a function that manipulates the resource.   We ensure that the close method on the resource is called after the manipulation function f.   We've declared the type of the resource using structural typing.   This means the compiler will accept anything that defines a close method.  We can then utilize withResource as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;withResource(new FileInputStream(new File("myFile.txt"))) { stream =&gt;&lt;br /&gt;  // Code using stream and returning something&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, this code is already giving us a form of duck-typing (called structural typing in Scala).   What about monkey patching?   This is where using the type class pattern can help.   Also note, that I prefer calling the type class pattern from haskell the "type trait" pattern in Scala.   This could be confusing, as C++ has a type trait pattern as well, however the fact that I use traits to define type classes is just as confusing.  In any case, please think of type traits and type classes, for the rest of this blog article as the same thing: A manifestation of type classes in Scala.&lt;br /&gt;&lt;br /&gt;Let's modify the withResource method to use a type class instead of a structural type.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;trait Resource[R] {&lt;br /&gt;  def close(r : R) : Unit&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is our Resource type class.   It defines a single method close.   We can now modify our withResource method to utilise this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;def withResource[A : Resource, B](resource : =&gt; A)(f : A =&gt; B) = {&lt;br /&gt;  val r = resource&lt;br /&gt;  try {&lt;br /&gt;    f(r)&lt;br /&gt;  } finally {&lt;br /&gt;    implicitly[Resource[A]].close(r)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice two things here.   First, we use the context-bounds constraint on the resource type parameter (A : Context).  This means that we have to look up our implicit type trait using the implicitly method.   We could, instead, give our method a well-defined implicit.   For now, we'll use the context-bound syntax as it's quickly starting to denote type traits in Scala.&lt;br /&gt;&lt;br /&gt;If we attempt to call this method as things stnad, we'll get an implicit lookup error:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre&gt;scala&gt; withResource(new java.io.StringReader("HAI")) { input =&gt; () }&lt;br /&gt;&lt;console&gt;:9: error: could not find implicit value for evidence parameter of type Resource[java.io.StringReader]&lt;br /&gt;       withResource(new java.io.StringReader("HAI")) { input =&gt; () }&lt;br /&gt;                                                     ^&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Now let's think through what we've done.   Any type can be used in the withResource method as long as an implicit is available for the given type in the implicit lookup resolution.   The simplest way to create an implicit for usage is to provide one directly.   This is easy to do in the REPL:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;scala&gt; implicit object stringResourceTrait extends Resource[java.io.StringReader] {&lt;br /&gt;         override def close(r : java.io.StringReader) = r.close()                    &lt;br /&gt;       }&lt;br /&gt;defined module stringResourceTrait&lt;br /&gt;&lt;br /&gt;scala&gt; withResource(new java.io.StringReader("HAI")) { input =&gt; () }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can see that we've satisfied the type system for the particular type java.io.StringReader.   Our old method was duck typed to use anything that had a close method.   We can actually get this same functionality with type traits as well.   Let's provide a default type trait in the Resource Companion object.   To do so, let's create a resource.scala file that looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;trait Resource[R] {&lt;br /&gt;  def close(r : R) : Unit&lt;br /&gt;}&lt;br /&gt;object Resource {&lt;br /&gt;  implicit def genericResourceTrait[A &lt;: { def close() : Unit }] = new Resource[A] {&lt;br /&gt;    override def close(r : A) = r.close()&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;What we've done is provide a method "genericResourceTrait" that is available on *every implicit search* for any Resource[_] type.  We've now gotten back to our previous functionality, and we can take this a bit farther.   What if we wanted to provide a specific implementation for a type?   In the case of resources,  Java provides a java.io.Closeable interface that most IO classes implement.   Creating a type trait implementation for this will give us the benefit of not needing to use reflection when we know a specific type.  Let's take our first crack at it.&lt;pre class="brush:scala"&gt;trait Resource[R] {&lt;br /&gt;  def close(r : R) : Unit&lt;br /&gt;}&lt;br /&gt;object Resource {&lt;br /&gt;  implicit def genericResourceTrait[A &lt;: { def close() : Unit }] = new Resource[A] {&lt;br /&gt;    override def close(r : A) = r.close()&lt;br /&gt;    override def toString = "Resource[{def close() : Unit }]"&lt;br /&gt;  }&lt;br /&gt;  implicit def jioResourceTrait[A &lt;: java.io.Closeable] = new Resource[A] {&lt;br /&gt;    override def close(r : A) = r.close()&lt;br /&gt;    override def toString = "Resource[java.io.Closeable]"&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;We now have a duck typed, reflection based implementation and an implementation for the java.io.Closeable interface.   We can prove that this works via the REPL by creating a mechanism of checking what type trait is used:&lt;pre class="brush:scala"&gt;scala&gt; def showTypeTraitUsed[A : Resource](a : A) = println(implicitly[Resource])&lt;br /&gt;showTypeTraitUsed: [A](a: A)(implicit evidence$1: Resource[A])Unit&lt;br /&gt;&lt;br /&gt;scala&gt; showTypeTraitUsed(new java.io.StringReader("HAI"))&lt;br /&gt;Resource[java.io.Closeable]&lt;br /&gt;&lt;br /&gt;scala&gt; showTypeTraitUsed(new { def close() : Unit = () })&lt;br /&gt;Resource[{def close() : Unit }]&lt;br /&gt;&lt;/pre&gt;We see that when passed a java.io.StringReader, something that subclasses java.io.Closeable, it uses the type trait defined for closeables.   When we pass an anonymous object that has a close method, it uses the structural-typed type trait instead.  What about monkey patching?   Well, using type traits, you can achieve a form of monkey patching.   Let's pretend an integer is a resource.   All we have to do is create a new type trait implementation for it.   Let's make that happen:&lt;pre class="brush:scala"&gt;scala&gt; implicit object intAsResource extends Resource[Int] {&lt;br /&gt;     | override def close(r : Int) = println("closing: " + r)&lt;br /&gt;     | }&lt;br /&gt;defined module intAsResource&lt;br /&gt;&lt;br /&gt;scala&gt; withResource(5)(println)&lt;br /&gt;5&lt;br /&gt;closing: 5&lt;br /&gt;&lt;/pre&gt;We define our close method to print out a string, so we can make sure it happens.   Finally, we can use an integer in our withResource method as if it were a resource, hence monkey-patching a close method onto it.  In fact, we could also use this mechanism to change the implementation of the Resource type trait in a particular context.   The key to this, as described in my book, is to ensure that you place your default implicitly available type trait implementation into the correct scope, such that &lt;ul&gt;&lt;li&gt;They can be overridden&lt;/li&gt;&lt;li&gt;They do not conflict&lt;/li&gt;&lt;/ul&gt;We can also use certain Scala tricks like having method return types be based on implicits available within scope.  Combining these all, you can create some rather interesting libraries, such as what is available in scala arm's &lt;a href="http://github.com/jsuereth/scala-arm/tree/typeclass-fix"&gt;typeclass-fix branch&lt;/a&gt;.  This branch contains a rather interesting flatMap that can detect if you are mapping to a Traversable type, and return a Traversable.  It will also detect if you are flatMapping to another Resource and return a new ManagedResource that will open/close that nested resource.   Finally, it also supports the standard flatMap implementation.Working with type classes in Scala adds a bit of overhead in amount of code, and some time to toy with the type system but can provide great flexibility in design.  I'm working on a library for interactive with Nexus, using webDAV protocol.   Using a "FileLike" type trait has been  helpful in the design, especially since certain methods can be optimised in particular algorithms where we know both types.   It's also useful because I've adapter several different WebDAV-enabled libraries to the API before finally deciding on the library I disliked the least.So in recap, let's look at why the typeclass pattern is so powerful in Scala:&lt;ul&gt;  &lt;li&gt;Can provide implementations for many differing types, in hierarchical fashion&lt;/li&gt;  &lt;li&gt;Can provide new type trait implementation from any scope&lt;/li&gt;  &lt;li&gt;Allows at-usage-site overriding of implementation details&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-1417374922965175779?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/1417374922965175779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=1417374922965175779' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1417374922965175779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1417374922965175779'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/07/monkey-patching-duck-typing-and-type.html' title='Monkey Patching, Duck Typing and Type Classes'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-1218006635133255393</id><published>2010-06-21T23:16:00.000-04:00</published><updated>2010-06-21T23:16:10.443-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comcast'/><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><category scheme='http://www.blogger.com/atom/ns#' term='issues'/><title type='text'>Comcast Privacy Fail</title><content type='html'>Wow, Comcast just amazed me again.  I haven't had a good rant post on here in a *long* time, but this is totally deserving of the biggest rant ever.  This  is the transcript from an &lt;b&gt;ONLINE&lt;/b&gt; chat my friend participated in (props goes to my friend for sharing).   I tried to scrub this somewhat clean, but perhaps there's enough here for Comcast to figure out internally who made the blunder and who's account was compromised.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;span style="color: red;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: red;"&gt;user John_ has entered room&lt;/span&gt;&lt;/p&gt;&lt;span style="color: red;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;John&lt;/b&gt;(Mon  Jun 21 2010 21:15:04 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I need a password for my &lt;a href="http://comcast.net/" target="_blank"&gt;comcast.net&lt;/a&gt; address&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: red;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: red;"&gt;analyst Ricky has entered room&lt;/span&gt;&lt;/p&gt;&lt;span style="color: red;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:15:06 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Hello John_, Thank you for contacting Comcast Live Chat Support. My name is Ricky. Please give me one moment to review your information.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:15:17 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;My pleasure to have you on this chat, John! I always remain committed and focused to provide you quality customer service at my fullest effort. Before anything else, I want to extend apologies for any trouble, inconvenience and frustration login issue has brought along your way. I still honestly hope you're fine. &lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:15:17 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;A comcastic day to you! How are you doing today?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:15:56 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;I've had better evenings Ricky. The comcast system is a bit screwed up&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:16:22 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry for that, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:16:27 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I understand that you need your user name and password to access your account online, am I correct?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:16:58 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;sort of. &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:17:14 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;i have a user name and password that i have used to log in and pay my bill for 2 years now&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:17:25 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;apparently that's not good enough to log in and download norton antivirus&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:17:38 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;so now i need *another* one. I understand it's supposed to be a &lt;a href="http://comcast.net/" target="_blank"&gt;comcast.net&lt;/a&gt; address&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:17:16 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I see, let me go ahead and assist you with that.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:17:19 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I do apologize for the inconvenience this issues has brought you,John. No worries as your service repsentative I will make sure that we get this issues resolved today.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:17:29 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;As your Comcast service repsentative, I want you to know that issue resolution and your satisfaction are my top priorities for today. Together, we can work this out, John. &lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:17:30 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Before we proceed resolving your issue, I need to verify some information in order for me to pull up your account. That is to insure the integrity of your account and for me to be able to assist you further. May I please have the account holder's full name, the account number, the complete billing address, and the last four digits of the account holder's SSN?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:18:08 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;I was able to get the email address from the system, but since i don't have a secret question, it wouldn't let me reset the password&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:18:34 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Let me go ahead and provide you your log ins so that you will not have issue accessing the account, okay?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:20:11 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Before we proceed resolving your issue, I need to verify some information in order for me to pull up your account. That is to insure the integrity of your account and for me to be able to assist you further. May I please have the account holder's full name, the account number, the complete billing address, and the last four digits of the account holder's SSN?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:21:20 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;John C Awesome  123 Amazing ST S Cool Town, USA 13124. xxxx&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:22:00 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;xxxxxxxxxxxxxxx  is an&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:21:49 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Thank you for helping me verify the account.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Sun May 21 2010 21:21:52 GMT-0400  (Eastern  Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Please allow me two to three minutes to pull up your account information so that we can resolve it in the most efficient way possible. Would that be okay with you?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:25:11 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;By the way, as a Comcast customer, I would like to tell you about the Service Protection Plan (SPP) we are offering. For a few dollars per month, you can have worry free protection for any in-home wiring problem. This is also simple and convenient, any problem with any Comcast service will be taken care of without any additional fees. Would you like to add it on your account today?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Sun May 21  2010 21:26:03 GMT-0400 (Eastern  Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Thank you for patiently waiting.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:26:29 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;def not Ricky&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:26:25 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I see here that you have a comcast user name: johnawesome@comcast.net&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:26:43 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;May I ask if you have the password.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:28:24 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;hmm, that doesn't look right. &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:28:44 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;I got the email address from the system and it said it was something else...let me doublecheck that&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:28:38 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Yes please.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:29:55 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;I went to this link: &lt;a href="http://www.idhelp.comcast.net/display/4n/search.asp?tab=search" target="_blank"&gt;http://www.idhelp.comcast.net/&lt;wbr&gt;&lt;/wbr&gt;display/4n/search.asp?tab=&lt;wbr&gt;&lt;/wbr&gt;search&lt;/a&gt;   and clicked on "I do not remember my Comcast user name or email address" &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:30:22 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;It then asked for my phone number. When i put that in, it said my email address was JohnAEWsome@comcast.net&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:30:03 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I see, that is the registered e mail on your account, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:31:22 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;what is the email address?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:31:19 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I see here that you have a comcast user name: johnawesome@comcast.net&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:32:01 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;your system says that's not correct&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:32:15 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;it's telling me it's johnaewsome@comcast.net&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:32:25 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry but that is the e mail address that I am seeing on your account.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:34:18 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;wonderful, well i don't have the password to that one either&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:34:19 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Just to set your expectation, we do not have the old password on your  email,John what can I do here on my end is to reset it into a new password, would that be okay?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:35:43 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;that's fine&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:36:46 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Thank you!&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:36:47 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;By the way, there will be a question survey after you click on the END SESSION button, please do take the survey this will be my supervisors basis of my performance, Thank you&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:37:27 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Would you mind if I ask you the security question?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:38:00 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;sure, but i can't guarantee i know the answer&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:38:07 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Thank you!&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:38:08 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Where did you go on your honeymoon?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:38:40 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;i'm not married&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:38:49 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry but that is the registered security question on your account.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:39:20 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;ricky i don't know what to tell you&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:39:03 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;May I ask for the four digit phone security pin instead.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:39:45 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;i've never been asked that ricky&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:39:31 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I see.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:39:31 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Since you are not able to provide me the security pin, a comcast repsentative will call you for verification. Please stay online while the call is in progress. &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Sun May 21 2010  21:40:06 GMT-0400 (Eastern  Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;are you really sure you want me to take that survey ricky?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:40:22 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;cause i'm getting real tired of spending my night dealing with comcast's crap systems&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:40:49 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry for that, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:41:00 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Please advise me if you have received the call.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:41:59 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;i ahven't&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:42:02 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;*haven't&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:41:57 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;We are calling you on your comcast phone right now, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:42:32 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;my comcast phone? &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:42:35 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;I don't have a comcast phone&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:42:38 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;i only have internet&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:42:18 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Yes, John,&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:42:50 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;why is your system so wrong?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:43:02 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry for that, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:43:23 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Ia m very sorry for the confusion.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:43:55 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;I'm not confused at all Ricky&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:44:15 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;In fact, i'm seeing things quite clearly at the moment. &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:44:06 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Please take note of your password, John. You will be needing this regularly.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:44:11 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Here is your password: xxxxxxxx   (all in lower case)&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:44:16 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;To make sure your issue is resolved, can you check for me if the log ins work, John?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:44:17 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Please advise me if you were able to log in successfully.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:45:52 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;Ricky, you gave me access to someone else's account. &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:45:57 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;That is your account, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:46:23 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;Now, why would you ask my address and account info if you were just going to ignore all of that&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:46:39 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;No&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:46:24 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;let me double check that, John. I am very sorry for that.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:46:49 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;don't be sorry&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:46:52 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;for me&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:46:57 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;be sorry for this other John Awesome&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:46:59 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;who lives at ervice address&lt;br /&gt;Mr John Awesome&lt;br /&gt;12345 xxxxxxx rd&lt;br /&gt;xxxxxxx, NOT MY STATE xxxxx-xxxxx&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Sun May 21 2010 21:47:05  GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;and account number is : xxxxxxxxxxx&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:47:15 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;none of that is close to what i provided above&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:47:36 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;May I ask for the phone number on the account please.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:48:06 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;Whose account?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:48:12 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;Mine or this other guys?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:48:24 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;Who is extremely lucky i'm a nice person and am not going to screw his account up&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:48:06 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;May I ask for the account number on your account please.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:48:33 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;Scroll up and look at it&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:48:52 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry but I was not able to pull up your account using the information you have provided.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:49:02 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;May i ask for the phone number on the account pleas.e&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:49:32 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;XXX-XXX-XXXX&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:49:36 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Thank you!&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:50:02 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Can you please check the address, for the address that appears here on my end is 123 AMAZING ST S COOL TOWN, USA 13124&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:51:19 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;yes, that is remarkably similar to the one i provided up above. An Exact duplicate one could say. &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:51:24 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Thank you for verifying,&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:51:44 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I see here that your user name is JOHNAEWSOME@comcast.net&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:52:09 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;No shit&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:52:12 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;that's what i told you&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:51:55 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Let me go ahead and reset the password, okay?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:52:21 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;By the way, I see here that Comcast Digital Voice is available in your area. Comcast's Digital Voice® uses advanced fiber optic network to provide reliable home phone service. Would you like to take advantage of this service?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:52:42 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;my question to you is what are you going to do for this other John Awesome? Just wait for him to call up and say that he can't access his account? &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:52:26 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Please take note of your password, John. You will be needing this regularly.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:52:47 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;hell no&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:52:50 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;damnit ricky pay attention&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:52:34 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Here is your password: xxxxxxxx (all in lower case)&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:52:42 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry for that, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:52:47 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:53:15 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;i've been screwing with comcast for 30 minutes now, you've compromised a user, and your'e trying to upsell?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:53:18 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;what's the matter with you?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:53:25 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry John, there was a system glitch and I was able to pull the wrong account.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:54:00 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;a system glitch? &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:54:06 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;that's crap&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:54:26 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;there were 4 opportunities to catch the mistake. there were not system glitches&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:54:07 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;To make sure your issue is resolved, can you check for me if the log ins work, John?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:54:21 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I understand you are frustrated, however I need to ask you to please refrain from using abusive language so that I may continue assisting you. Keeping our dialogue professional and courteous will allow me to better serve you. If you continue to use inappropriate language, I will be forced to end the chat session.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:55:07 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;actually, what's a number i can use to call your manager&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:55:30 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;You can call my manager at this number: 1-888-266-2278&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:56:04 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Just to recap. I gave you your Comcast email user name and password. Would there be anything else I can assist you with?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:57:51 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;No, there's nothing that you can personally do Ricky. &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:57:47 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Were you able to log in, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:58:42 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;Yes i was able to.  Also, the number you gave me is the main comcast line&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:58:54 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;is your manager a automated phone system?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:58:55 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;That is correct, John. For that is the only way you can contact our manager.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:59:26 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;so how do i reference this chat?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:59:32 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;or speak to a person?&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:59:26 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I will provide you my ID for your reference, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 21:59:55 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;that would be useful&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 21:59:54 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Here is my ID: XXXXXXXXXXXXXXXXXXXXXXXXXXX&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 22:00:32 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;that should be fun to communicate over the phone&lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 22:01:03 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;Would there be anything else, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;&lt;b&gt;Ricky&lt;/b&gt;(Mon  Jun 21 2010 22:01:17 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue;"&gt;I am very sorry for the inconvenience, John.&lt;/span&gt;&lt;/p&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&lt;b&gt;John_&lt;/b&gt;(Mon  Jun 21 2010 22:01:44 GMT-0400 (Eastern Daylight Time))&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: green;"&gt;i *highly* recommend resetting johnawesome@comcast.net's password&amp;nbsp; &lt;/span&gt;&lt;/p&gt;&lt;span style="color: green;"&gt;&lt;/span&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/1673113361032868171-1218006635133255393?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/1218006635133255393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=1218006635133255393' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1218006635133255393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1218006635133255393'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/06/comcast-privacy-fail.html' title='Comcast Privacy Fail'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-8731757306606607248</id><published>2010-06-12T10:50:00.000-04:00</published><updated>2010-06-12T10:50:17.745-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='higher kinded types'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Preserving Types and Differing Subclass Type Parameters</title><content type='html'>My last post was on keeping your type annotations as simple as possible to solve your problem.   It is important to keep your type system h4x0r-y as simple as possible to solve the given problem, but no simpler.   This gives users the greatest flexibility.   So, when doing some kind of query from a Traversable type that does *not* return the original type, you can simply take type Traversable[T], where T is a parameter to your function as well.&lt;br /&gt;&lt;br /&gt;I started off the last post attempting to solve a problem I did not have.   However, what if I did have this problem?   That is:   I want to preserve the type of a subclass of traversable for the return of my function.   The subclass may have a differing type parameter then the traversable, or in my contrived example:  TestClass[X] extends Traversable[Y].   Well, let's start digging into a solution.&lt;br /&gt;&lt;br /&gt;Let's ignore things that did *not* work in the last post.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;def foo[A, M[T] &lt;: Traversable[T]](m : M[A]) = ... // M has differing type parameter, or multiple&lt;br /&gt;def foo[A, M[_] &lt;: Traversable[_]](m : M[A]) = ... // A is not the parameter to Traversable..&lt;br /&gt;def foo[A : Manifest, M &lt;: Traversable[A]](m : M) = ... // Type Inference does not work, but this *does* abide by the type system.&lt;br /&gt;&lt;/pre&gt;Let's see if we can fix the type inference problem on the last option.   To do so, we need to find a way to help the type system out (as it's not very fond of inferring types out of a subclass).  Let's take a quick crack at this:&lt;pre class="brush:scala"&gt;def foo[C &lt;: Traversable[_]](c : C) = new {&lt;br /&gt;    // We now know the type of C from inference.  Let's see if we can infer the type&lt;br /&gt;    // associated with the Traversable *correctly*&lt;br /&gt;    def apply[X : Manifest](t : Traversable[X]) = {&lt;br /&gt;      // We're going to print the inferred Traversable type to make sure it comes out correctly&lt;br /&gt;      println(implicitly[Manifest[X]])&lt;br /&gt;      // The resulting type should be the infered C&lt;br /&gt;      c&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;What we've done is created a curried function that *takes the same parameter twice*.   The first time we infer it's full type C and ensure it's a subclass of Traversable.   The second function (apply) will infer the type parameter to the Traversable subclass and reify it into a Manifest.    We print this value to ensure we've done everything correctly.   Now it's time to test and see if we've achieved our goal!&lt;pre class="brush:scala"&gt;// We create a subclass where the type parameter to Traversable is *different* from the subclass.&lt;br /&gt;class Temp[X] extends Traversable[Int] {&lt;br /&gt;    def foreach[U](f : Int =&gt; U) : Unit = f(5)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// This is now interpreter output&lt;br /&gt;scala&gt; val x = new Temp[String]&lt;br /&gt;x: Temp[String] = line2(5)&lt;br /&gt;&lt;br /&gt;scala&gt; foo(x)(x)&lt;br /&gt;Int&lt;br /&gt;res0: Temp[String] = line2(5)&lt;br /&gt;&lt;/pre&gt;So we have the unfortunate ugliness of having to send the parameter to *two* function, since we split the type inference in half,  However, notice that we've inferred the type parameter to Traversable correctly!   Also notice that the return type is Temp[String], which is exactly what we desired.So, we had to jump a few hoops to get what we want.   The unfortunate truth is that this kind of inference can't be done all in one go (And if you figure out a way, please let me know!!!).   However, it's still possible to manipulate the type system to do what we want, albeit at the cost of some extra ugliness.Why might I want to perform this kind of trickery?   Let's suppose Temp[String] is an immutable type that acts like a Traversable on Ints.   I have a method that wants to iterate those Ints and create some kind of new Temp[String] based on what it found.   To do this, I'm using a builder pattern with implicit builders.   Let's take a look at the new signature I can use to accomplish my goal:&lt;pre class="brush:scala"&gt;def foo[C &lt;: Traversable[_] : Builder](c : C) = new {&lt;br /&gt;    def apply[X : Manifest](t : Traversable[X]) = {&lt;br /&gt;&lt;br /&gt;      // We're going to use the traversable, and we need the manifest of X to do some&lt;br /&gt;      // specialized calculations, maybe some Array fun.&lt;br /&gt;      val result = doSomethingWithTraversableUsingXManifest(t)&lt;br /&gt;&lt;br /&gt;      // Construct a new C using its Builder with a modified Attribute&lt;br /&gt;      implicitly[Builder[C]].copyWithModify(c, ModifyAttribute(MyAttribute, result))&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, this is now possible!   I'm making the Builder / Modify attribute magic purposefully hazy as I hope to cover this in a blog article in the near future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-8731757306606607248?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/8731757306606607248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=8731757306606607248' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8731757306606607248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8731757306606607248'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/06/preserving-types-and-differing-subclass.html' title='Preserving Types and Differing Subclass Type Parameters'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-1231496576682416006</id><published>2010-04-27T21:05:00.001-04:00</published><updated>2010-04-28T07:58:17.728-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='types'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>On higher kinded and existential types,...no stereos</title><content type='html'>So I was recently bit by a type issue with existential types until someone forced me to start thinking again.   Let's start with a good example of what I was trying to do:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;def foo[A, M[T] &amp;lt;: Traversable[T]](m : M[A]) : A = m.head&lt;br /&gt;def foo2[A, M[_] &amp;lt;: Traversable[_]](m : M[A]) : A = m.head &lt;/pre&gt;foo2 will fail to compile with a type error.  What gives!  Aren't these the same?  Well, no they are not.  Let's see if we can reason through the type signature we've written.    For foo, A is any type and M is a higher kinded type.  M has a type parameter T.  M is also some kind of subclass of Traversable.   Also, the type parameter T on M is *the same* type parameter used for the Traversable parent (i.e. defined trait/class M[T] extends Traversable[T]).  Now for foo2, it's a bit different.  A is any type.  M is some higher kinded type (takes a type parameter) but in this case we don't acre which.   M is also a subclass of Traversable, and once again we don't care about the type parameter to Traversable.   The big difference here is that we don't care about the type parameters to M or Traversable, meaning they could be different types.   Now when we define parameter m, we're looking at M[A] &amp;lt;: Traversable[_] or, in other words, we still know nothing about the type in the traversable.  Let's try to prove our intuition about foo2 by capturing the manifest of type parameter A and see if it has any correlation to the type in the traversable:  &lt;br /&gt;&lt;pre class="brush: scala"&gt;def foo[A : Manifest, M[_] &amp;lt;: Traversable[_]](m : M[A]) : A = {&lt;br /&gt;  println(implicitly[Manifest[A]])&lt;br /&gt;  m.head.asInstanceOf[A]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Temp[X] extends Traversable[Int] {&lt;br /&gt;  override def foreach[U](f : Int =&amp;gt; U) : Unit = f(5); ()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;foo(new Temp[String]) // Prints java.lang.String -&amp;gt; NOT Int&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, the compiler has capture the String type parameter, not the Int as we really wanted to capture in this method.  Let's see if we can correct our mistake:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;def foo[A : Manifest, M[X] &amp;lt;: Traversable[X]](m : M[A]) : A = {&lt;br /&gt;  println(implicitly[Manifest[A]])&lt;br /&gt;  m.head.asInstanceOf[A]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Temp[X] extends Traversable[Int] {&lt;br /&gt;  override def foreach[U](f : Int =&amp;gt; U) : Unit = f(5); ()&lt;br /&gt;}&lt;br /&gt;foo(new Temp[String]) //THis line errors -&amp;gt;&lt;br /&gt;&lt;console&gt;:9: error: inferred type arguments [String,Temp] do not conform to method foo's type parameter bounds [A,M[X] &amp;lt;: Traversable[X]]&lt;br /&gt;       foo(x)&lt;br /&gt;&lt;/console&gt;&lt;/pre&gt;Ok, so I've seen a lot of code with this M[X] &amp;lt;: Traversable[X]...   This should work right?   Well, let's think it through:   M[X] &amp;lt;: Traversable[X] implies that the type M is higher-kinded (takes a type parameter).   It also implies that it extends Traversable, and finally that The type parameter to Traversable should be *the same* as the type parameter to M.  It's this last piece we've messed up.   Our Temp class does take a type parameter, but it has nothing to do with the type parameter in its traversable parent.   This distinction is important, especially with collections.   M[X] &amp;lt;: Traversable[X] can capture an awful lot of collection types, however it will miss any collection where the type is known...  In other words, if I defined something like &lt;br /&gt;&lt;pre&gt;IOByteStream extends Stream[Byte]&lt;/pre&gt;then &lt;br /&gt;&lt;pre&gt;M[X] &amp;lt;: Stream[X]&lt;/pre&gt;will fail to capture this type!  Let's take one more attempt, this time trying to capture a subclass of Traversable where the Traversable's type parameter is captured in a manifest.  &lt;br /&gt;&lt;pre class="brush: scala"&gt;def foo[A : Manifest, M &amp;lt;: Traversable[A]](m : M) : A = {&lt;br /&gt;  println(implicitly[Manifest[A]])&lt;br /&gt;  m.head&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Temp[X] extends Traversable[Int] {&lt;br /&gt;  override def foreach[U](f : Int =&amp;gt; U) : Unit = f(5); ()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;foo[Int,Temp[String]](new Temp[String]) //We need to use our types here&lt;br /&gt;&lt;/pre&gt;Well the method compiles, but we have the issue that the typer cannot infer our types!  At least we managed to express what we wanted... or did we?  Our method does not care about the actual subtype of Traversable, and does not need to capture it.   If you look, the return type is A, not M.  Therefore we should be able to take in just a Traversable, like so:  &lt;br /&gt;&lt;pre class="brush: scala"&gt;def foo[A : Manifest](m : Traversable[A]) : A = {&lt;br /&gt;  println(implicitly[Manifest[A]])&lt;br /&gt;  m.head&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Temp[X] extends Traversable[Int] {&lt;br /&gt;  override def foreach[U](f : Int =&amp;gt; U) : Unit = f(5); ()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;foo(new Temp[String])  //Prints Int and returns 5&lt;br /&gt;&lt;/pre&gt;I purposely made me initial example odd so I could make this point:  When using the type system, try to keep things as simple as possible.  Expand your definitions as needed, or when assumptions are proven invalid.  Here, we had no need for the actual subtype of Traversable and yet we were focused on getting the signature right to capture a subtype.  This is important for developers to learn, and even *more* important for library authors.  When using type parameters, make sure to reason through the signatures to be sure they capture what is desired - no more or no less.  Just for kicks, let's try a method were we *do* care about the original subtype, and wish to preserve it, yet also need to use the Traversable's type parameter.  What can we do?  Let's attempt to capture both type parameters:  &lt;br /&gt;&lt;pre class="brush: scala"&gt;def foo[A : Manifest, B, M[X] &amp;lt;: Traversable[A]](m : M[B]) : M[B] = {&lt;br /&gt;  println(implicitly[Manifest[A]])&lt;br /&gt;  m&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Temp[X] extends Traversable[Int] {&lt;br /&gt;  override def foreach[U](f : Int =&amp;gt; U) : Unit = f(5); ()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;foo[Int,String, Temp](new Temp[String]) //We need to use our types here again&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can see we've captured both type parameters in A and B, however once again the Scala type inferencer cannot distinguish our meaning without some help.   Is there anything we can do here?&lt;br /&gt;&lt;br /&gt;Unfortunately... I don't actually know of a way to help the type inferencer here.  I also realized that in my situation, that kind of a requirement was completely unnecessary....   If anyone has any ideas for the academic excercise, please let me know.&lt;br /&gt;&lt;br /&gt;Since the new collections API starts throwing more type issues in the face of every day developers, expect a new series from me: "Enough Type magic to work with Scala Collections".   As I figure out ideal ways to deal with new type signatures required in abstract methods, I'll try to post findings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-1231496576682416006?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/1231496576682416006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=1231496576682416006' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1231496576682416006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1231496576682416006'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/04/on-higher-kinded-and-existential.html' title='On higher kinded and existential types,...no stereos'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-1949815037387842732</id><published>2010-04-15T18:19:00.000-04:00</published><updated>2010-04-15T18:19:55.156-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='horrible misinterpretation'/><category scheme='http://www.blogger.com/atom/ns#' term='monad'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Leaky Monads Talk</title><content type='html'>Here's my talk from ScalaDays 2010 on how I completely ruin a theoretical concept:&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://docs.google.com/present/embed?id=dfqn4jb_82gs6zt9cc" frameborder="0" width="410" height="342"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://github.com/jsuereth/scala-arm"&gt;source code is available on github&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thanks to everyone who was there!  Special thanks to Adrian for pointing out my misinterpretation of the implicit spec (ignore slides 15/16).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-1949815037387842732?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/1949815037387842732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=1949815037387842732' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1949815037387842732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1949815037387842732'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/04/leaky-monads-talk.html' title='Leaky Monads Talk'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-2746678288884186744</id><published>2010-03-10T22:56:00.014-05:00</published><updated>2011-10-19T09:32:46.052-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delimited continuations'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>How you should think about Delimited Continuations in Scala</title><content type='html'>Scala 2.8.x is going to have a new delimited continuations plugins.   Delimited continuations are interesting animals, and I've seen some decent articles about them.   I'm going to portray here how you should think about delimited continuations in a way that will help you know how to make use of them in your coding.&lt;br /&gt;&lt;br /&gt;Let's take a look at the &lt;a href="http://en.wikipedia.org/wiki/Delimited_continuation"&gt;wikipedia definition&lt;/a&gt; of delimited continuations:&lt;br /&gt;&lt;blockquote&gt;a &lt;b&gt;composable continuation&lt;/b&gt;, &lt;b&gt;delimited continuation&lt;/b&gt; or &lt;b&gt;partial continuation&lt;/b&gt;, is a "slice" of a &lt;a href="http://en.wikipedia.org/wiki/Continuation" title="Continuation"&gt;continuation&lt;/a&gt; &lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Stack_frame" title="Stack frame"&gt;frame&lt;/a&gt; that has been &lt;a href="http://en.wikipedia.org/wiki/Reification_%28computer_science%29" title="Reification (computer science)"&gt;reified&lt;/a&gt; into a &lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Function_%28computer_science%29" title="Function (computer science)"&gt;function&lt;/a&gt;.&lt;/blockquote&gt;&lt;br /&gt;This is basically saying that a delimited continuation is marking a particular section of a program in such a way the compiler can "reify" it into a Function (or Closure if you will).  In fact, the compiler can use similar semantics to how a closure is made, the difference here is in how you make arguments to functions.   Let's take a look at a simple Scala delimited continuation example and try to de-mystify:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;import scala.continuations._&lt;br /&gt;import scala.continuations.ContextControl._&lt;br /&gt;&lt;br /&gt;object SimpleCont {&lt;br /&gt;&lt;br /&gt;  def main(args : Array[String]) : Unit = {&lt;br /&gt;    val result = reset {&lt;br /&gt;       1 + shift { k =&amp;gt; k(k(5)) } + 1                   &lt;br /&gt;    }&lt;br /&gt;    Console.println(result)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This simple example prints 9 to the screen.   So what is happening?   Well, let's look at the definition: A "slice" of a continuation frame that has been reified into a function....&lt;br /&gt;&lt;br /&gt;Well, we know reify essentially means  to make it a first-class citizen (or first-class-function).   So what is our "slice of continuation frame"?   It's everything inside the reset block.   This is where the "delimited" portion comes in.  We're using reset to as an outer-bounds for the compiler to capture code and reify it into a function.   In doing so, the compiler essentially takes all shift keywords and turns them into arguments for the reified function.   Let's look at what our reified function is equivalent to in the above example:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;reset {&lt;br /&gt;       1 + &lt;span style="color: #117711; font-weight: bold;"&gt;shift { k =&amp;gt; k(k(5)) }&lt;/span&gt; + 1                   &lt;br /&gt;  }&lt;br /&gt;  val reifiedFunction = { shiftVal1 : Int =&amp;gt; &lt;br /&gt;       1 + &lt;span style="color: #117711; font-weight: bold;"&gt;shiftVal1&lt;/span&gt; + 1&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice how the entire &lt;i&gt;shift {..}&lt;/i&gt; expression is converted into an argument of the reified function.  That's where the continuation comes in.  All code inside the reset, minus the shift expressions, is turned into continuations... Something that could be called later and/or multiple times.   For the real magic, let's take a look at this shift operation.&lt;br /&gt;&lt;br /&gt;The shift command takes  a function as an argument.  This function takes another function as its only parameter (higher-order) and that function *is* the reified continuation.   So... strangely enough, the shift expressions are turned into arguments on functions *passed into the functions defined in the shift expression*.  Yes, this blew my mind at first, but becomes very interesting and handy.  Not only that, it's a true inversion of control.   &lt;br /&gt;&lt;br /&gt;In this simple example, the portion of code defined in shift *becomes* the main execution path, and calls the reified continuation.  Let's look at the translated code side-by-side&lt;br /&gt;&lt;br /&gt;&lt;div style="width: 700px;"&gt;&lt;div style="float: left; width: 50%;"&gt;&lt;pre class="brush: scala"&gt;object SimpleCont {&lt;br /&gt;&lt;br /&gt;  def main(args : Array[String]) : Unit = {&lt;br /&gt;    val result = reset {&lt;br /&gt;       1 + &lt;span style="color: #117711; font-weight: bold;"&gt;shift { &lt;span style="color: #771111; font-weight: bold;"&gt;k =&amp;gt; k(k(5))&lt;/span&gt; }&lt;/span&gt; + 1                   &lt;br /&gt;    }&lt;br /&gt;    Console.println(result)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="float: right; width: 50%;"&gt;&lt;pre class="brush: scala"&gt;object SimpleCont {&lt;br /&gt;&lt;br /&gt;  def main(args : Array[String]) : Unit = {   &lt;br /&gt;     // Reified function&lt;br /&gt;     val &lt;span style="color: #771111; font-weight: bold;"&gt;k&lt;/span&gt; = { shiftVal1 : Int =&amp;gt;&lt;br /&gt;       1 + &lt;span style="color: #117711; font-weight: bold;"&gt;(shiftVal1)&lt;/span&gt; + 1&lt;br /&gt;     }&lt;br /&gt;     val result = &lt;span style="color: #771111; font-weight: bold;"&gt;k(k(5))&lt;/span&gt;&lt;br /&gt;     Console.println(result)&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;As you can see, we've completely reversed the shifts and the resets.  Let's try to understand an example which involves two variables.  The Continuations paper includes an example that takes the cartesian product of two lists (i.e.  List(A,B) and List(C,D) =&amp;gt; List((A,C), (A,D),(B,C),(B,D)) ).   First the example code straight from &lt;a href="http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf"&gt;the paper&lt;/a&gt; (with a few modifications for simplicity):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;implicit def reflectiveList[A](xs:List[A]) = new {&lt;br /&gt;      def reflect[B]() : A @cps[List[B], List[B]] = shift { k:(A =&amp;gt; List[B]) =&amp;gt;&lt;br /&gt;        xs.flatMap(k)&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    reset {&lt;br /&gt;      val left = List("x","y","z")&lt;br /&gt;      val right = List(4,5,6)&lt;br /&gt;      List((left.reflect[(String,Int)], right.reflect[(String,Int)]))&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;// result: cartesian product&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let's decompose this one a bit.   The implicit reflective stuff is used to enabled the reflective method on lists.  We'll analyze reflective soon, but for now, notice that it calls shift.   This means that calls to reflective are equivalent to calls to shift.  Let's try to figure out what the reified continuation is by first "inlining" all the code:&lt;br /&gt;&lt;div style="width: 600px;"&gt;&lt;div style="float: left; width: 50%;"&gt;&lt;pre class="brush: scala"&gt;reset {&lt;br /&gt;  val left = List("x","y","z")&lt;br /&gt;  val right = List(4,5,6)&lt;br /&gt;  List(Tuple2(&lt;br /&gt;      &lt;span style="color: #117711; font-weight: bold;"&gt;left.reflect[Any],&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: #111199; font-weight: bold;"&gt;right.reflect[Any]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  ))&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="float: right; width: 50%;"&gt;&lt;pre class="brush: scala"&gt;reset {&lt;br /&gt;  val left = List("x","y","z")&lt;br /&gt;  val right = List(4,5,6)&lt;br /&gt;  List(Tuple2(&lt;br /&gt;        &lt;span style="color: #117711; font-weight: bold;"&gt;shift { k:(A =&amp;gt; C[B]) =&amp;gt;&lt;br /&gt;          left.flatMap(k)&lt;br /&gt;        },&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #111199; font-weight: bold;"&gt;shift { k:(A =&amp;gt; C[B]) =&amp;gt;&lt;br /&gt;          right.flatMap(k)&lt;br /&gt;        }&lt;/span&gt;&lt;br /&gt;  ))&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;First of all, Notice the new type signatures on the shift expressions (without the generics).  We'll discuss these more in depth later, but if hand-reify the continuation, we need to make sure we match the signatures expected from the shift expressions.  Let's take our first crack at it:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:scala"&gt;val reified : = { (shift1, shift2) =&amp;gt;&lt;br /&gt;  List(Tuple2(&lt;br /&gt;        &lt;span style="color: #117711; font-weight: bold;"&gt;shift1&lt;/span&gt;,&lt;br /&gt;        &lt;span style="color: #111199; font-weight: bold;"&gt;shift2&lt;/span&gt; &lt;br /&gt;  ))&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Well, that seems simple enough...  except we're not creating the lists in the reified function!   Ah... remember, we're only reifying the continuation piece.  We can directly execute the portion of the code that are directly executable.  Let's try to completely unwind the code and translate it:&lt;br /&gt;&lt;pre class="brush: scala"&gt;// Original Code&lt;br /&gt;reset {&lt;br /&gt;      val left = List("x","y","z")&lt;br /&gt;      val right = List(4,5,6)&lt;br /&gt;      &lt;span style="color: #660000; font-weight: bold;"&gt;List((&lt;span style="color: #117711; font-weight: bold;"&gt;left.reflect[(String,Int)]&lt;/span&gt;, &lt;span style="color: #111199; font-weight: bold;"&gt;right.reflect[(String,Int)]&lt;/span&gt;))&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;span style="color: #660000; font-weight: bold;"&gt;val reified : (String, Int) =&amp;gt; List[Any] = { (shift1, shift2) =&amp;gt;&lt;br /&gt;  List(Tuple2(&lt;br /&gt;        &lt;span style="color: #117711; font-weight: bold;"&gt;shift1,&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #111199; font-weight: bold;"&gt;shift2&lt;/span&gt;&lt;br /&gt;  ))&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;//Original reset was here...&lt;br /&gt;val left = List("x","y","z")&lt;br /&gt;val right = List(4,5,6)&lt;br /&gt;&lt;span style="color: #117711; font-weight: bold;"&gt;left.flatMap( l =&amp;gt; &lt;span style="color: #111199; font-weight: bold;"&gt;right.flatMap(r =&amp;gt; reified(l,r)&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Well that's interesting....   This is the effect of apply delimited continuations and should help you begin to reason about them and how they operate, however the actual truth of the matter is, your code is transformed differently.  Let's take a look at what is really happening, just so we can dig deeper if needed.   Technically, there are two reified continuation (for the two shifts) so let's make our hand-reified code do the same:&lt;br /&gt;&lt;pre class="brush: scala"&gt;//Original reset was here...&lt;br /&gt;val left = List("x","y","z")&lt;br /&gt;val right = List(4,5,6)&lt;br /&gt;val reified1 : (String =&amp;gt; List[Any]) = { shift1 =&amp;gt;&lt;br /&gt;  val reified2 : (Int =&amp;gt; Any) = { shift2 =&amp;gt;&lt;br /&gt;        Tuple2(shift1,shift2)     &lt;br /&gt;  }&lt;br /&gt;  right.flatMap(reified2)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;left.flatMap(reified1)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So this is where it gets strange.   We create a function "refiied1" which is passed to the first shift expression (left.flatMap).   This contains the outer continuation.   We then have a second call to shift.  This means there is a second continuation generated inside the first continuation.   The second function is responsible for generating the tuples.   This is based to the second shift expression "right.flatMap".  As you can see, every time you use the shift function, you're causing the compiler to generate a new continuation to defer the next set of processing.   You can also see how in "pure" form, this has a very nested structure, whereas the original code was very "flat".  Also, because work is automatically defered into continuation functions, you can use this style for concise and performant asynchronous work.&lt;br /&gt;&lt;br /&gt;Let's take a mini-dive into a continuations for automated resource management.  First, let's make our sample file:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre&gt;HAI!&lt;br /&gt;&lt;br /&gt;O&lt;br /&gt;MY!&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Now, let's right a continuation-based program to read each line and give us the size of it.  I'm purposely making the code slightly confusing here to demonstrate the inversions.   Well, let's start off with a mechanism of "reflecting" or "inverting" a resource for delimited continuations.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;trait Resource[+R] {&lt;br /&gt;      def flatMap[U](f : R =&amp;gt; U) : U&lt;br /&gt;      def reflect[B]() : R @cps[B,B] = shift { k : (R =&amp;gt; B) =&amp;gt; flatMap(k) }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def resource[R &amp;lt;: Closeable](acquire : =&amp;gt; R) = new Resource[R] {&lt;br /&gt;      override def flatMap[U](f : R =&amp;gt; U) : U = {&lt;br /&gt;        val x = acquire&lt;br /&gt;        try {&lt;br /&gt;          f(x)&lt;br /&gt;        } finally {&lt;br /&gt;          System.out.println("Closing Resource!")&lt;br /&gt;          x.close()&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We define a simple Resource trait that gives us a flatMap (some may call this "using") and a reflect (or inverse) method.   This will let us "flatten" resource usage inside a reset block.   The next component is the implementation of resource for any java.io.Closeable implementation.   This will take a function to acquire a resource and implement the flatMap method correctly.   This should look *very* similar to the reflect method defined on lists...  One might even say this method works to flatten any monad ;)&lt;br /&gt;&lt;br /&gt;Now, let's get really dirty and define an inversion on java.io.InputStream to deal with lines:&lt;br /&gt;&lt;pre class="brush: scala"&gt;def reflect[A &amp;lt;: InputStream](input : A) = new {&lt;br /&gt;      def each_line[B] : String @cps[B,List[B]] = shift { &lt;br /&gt;          k : (String =&amp;gt; B) =&amp;gt;&lt;br /&gt;        val b = new BufferedReader(new InputStreamReader(input))&lt;br /&gt;        var line = b.readLine&lt;br /&gt;        var list = ListBuffer[B]()&lt;br /&gt;        while(line != null) {&lt;br /&gt;          list += (k(line))&lt;br /&gt;          line = b.readLine&lt;br /&gt;        }&lt;br /&gt;        list.toList&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We've defined our reflect method to work on every line within the file.  It builds up a list and returns it as the final result.  You'll notice the shift call takes a function requiring a String and returning a "B".   The fun type-system issue we have to deal with here is you need to know the result of the reified continuation in the return value for each_line.   We'll get to that more in a moment, but for now make note of this.&lt;br /&gt;&lt;br /&gt;Alright, now let's define our simple function to manipulate every line in a file:&lt;br /&gt;&lt;pre class="brush: scala"&gt;reset {&lt;br /&gt;      val input = resource(new FileInputStream("test.txt")).reflect[Any] //We cheat on the return value here!&lt;br /&gt;      val line = reflect(input).each_line[Int] //We need to know the continuation returns an Int Here!!!&lt;br /&gt;      System.out.println(line)&lt;br /&gt;      line.size&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Wow... so really all we're doing is grabing our input, inverting to the "each_line" call and calling line.size after printing the line to the console.&lt;br /&gt;&lt;br /&gt;So what's the output look like?&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;scala&amp;gt; Main.resourceTest()&lt;br /&gt;HAI!&lt;br /&gt;&lt;br /&gt;O&lt;br /&gt;MY!&lt;br /&gt;&lt;br /&gt;Closing Resource!&lt;br /&gt;res0: Any = List(4, 0, 1, 3, 0)&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This is great!   It's doing what we wanted.   Notice how we've "flattened" the code substantially compared with other methods.  Contrast the above with the following:&lt;br /&gt;&lt;pre class="brush: scala"&gt;val input = new scala.io.magic.File("test.txt")&lt;br /&gt;for { &lt;br /&gt;  stream &amp;lt;- file.managedInput&lt;br /&gt;  line &amp;lt;- input.lines&lt;br /&gt;} yield line.size&lt;br /&gt;&lt;/pre&gt;You'll notice a few similarities (in my made up library).   For-expressions are another area in scala where you're reifing portions of the code into closures and passing them to flatMap blocks.  However, delimited continuations open the doors to way more than flatMap.   Let's go back to that typing issue though.If you remember, I was returning Any because I was being lazy with my type annotations when reflecting the input stream.   Let's use the correct annotation:&lt;br /&gt;&lt;pre class="brush: scala"&gt;reset {&lt;br /&gt;      val input = resource(new FileInputStream("test.txt")).reflect[List[Int]]&lt;br /&gt;      val line = invert(input).each_line[Int] //We need to know the continuation returns an Int Here!!!&lt;br /&gt;      System.out.println(line)&lt;br /&gt;      line.size&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;So... what do these type annotations mean?   In the case of the resource's reflect method, the type annotation is the ultimate result from the reset call (i.e. the result of the reified continuation) because of how we defined flatMap on Resource.   The type annotation for each_line describes the type the resulting List of processed lines should contain... i.e. the result of the last portion of the continuation.  If we were to hand-code this reset piece we'd have:&lt;br /&gt;&lt;pre class="brush: scala"&gt;val rcont1 : (FileInputStream =&amp;gt; List[Int]) = { &lt;br /&gt;  inputStream =&amp;gt;&lt;br /&gt;     val rcont2 : (String =&amp;gt; Int) = { line =&amp;gt;&lt;br /&gt;        System.out.println(line)&lt;br /&gt;        line.size&lt;br /&gt;     }&lt;br /&gt;     val b = new BufferedReader(new InputStreamReader(inputStream))&lt;br /&gt;     var line = b.readLine&lt;br /&gt;     var list = ListBuffer[B]()&lt;br /&gt;     while(line != null) {&lt;br /&gt;        list += (rcont2(line))&lt;br /&gt;        line = b.readLine&lt;br /&gt;      }&lt;br /&gt;      list.toList&lt;br /&gt;  }&lt;br /&gt;  resource(new FileInputStream("test.txt")).flatMap(rcont1)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So... delimited continuations certainly use far less code here.  The understanding of what's going on under-the-covers perhaps needs some good terminology/consistent paradigms to be useful in library-form (i.e. if I make each_line or reflective part of a standard library).   Also, it's my opinion that the type-inference barrier for the @cps annotation should be looked into.  Perhaps we can invent creative ways to infer the types in an inverted fashion when using delimited continuations.  In the meantime, the compiler will complain until you figure out the correct types, so it could be worse ;)&lt;br /&gt;&lt;br /&gt;I plan to post a bit more about delimited continuations after I have some useful I/O related tools built up around them.   Let me know if you find this post helpful.  I'd also like to clarify that my "hand-reification" is not really how scala does reification, but close enough for understanding the concepts.&lt;br /&gt;&lt;br /&gt;Also, there's some interesting continuation-based actors code in the paper that I'm going to try to dig into here when I have the time!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-2746678288884186744?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/2746678288884186744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=2746678288884186744' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2746678288884186744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2746678288884186744'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/03/how-you-should-think-about-delimited.html' title='How you should think about Delimited Continuations in Scala'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-735483212096690274</id><published>2010-02-28T10:12:00.001-05:00</published><updated>2010-02-28T10:47:18.536-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='functional vs. oo'/><category scheme='http://www.blogger.com/atom/ns#' term='goat rodeo'/><title type='text'>Actor Styles... OO, Functional or Blended...</title><content type='html'>I had the privilege of a free cup of coffee with David Pollak when I was in the bay area recently.  He was describing his new goat-rodeo library when he showed me the interface for his "Worker" class (which is similar to an Actor class).   He made a comment about "being annoyed with writing all those case statements" in actors, and so figured out a method using reflection and method overloading to define an actor that merely responds to all messages it receives.   I'm sure there was more to it than this, but I believe he's partially solved an OO issue I complained about in an &lt;a href="http://suereth.blogspot.com/2009/04/partial-functions-inheritance.html"&gt;earlier blog about partial functions and inheritance&lt;/a&gt;.  Let's take a bit to remember that solution to the issue.&lt;br /&gt;&lt;br /&gt;The crux of the problem is the blend of OO and functional.   Functions are composable.  You can have one function take another and compose them all day long.   Objects are also composable.  One object can take another object and utilize it all day long.   Methods (functions attached to objects) are not as composable.  Scala traits give you means to compose with them, but all your composition is done at instantiation time (i.e. mixing in traits, inheritance, etc.).  Now we come to the main issue.  An Actor is an abstract class that you subclass.  This leads one to compose behavior through traits (similar to other OO-style programs in Scala), but the method of doing so is a bit strange.   We start with our "FinalMixinActor" class&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;trait BaseActor extends Actor {&lt;br /&gt;&lt;br /&gt;   def makeMessageHandler() : PartialFunction[Any,Unit] = {&lt;br /&gt;      case x =&gt; //Unhandled message, assume design flaw!&lt;br /&gt;            error("Unknown message: " + x)    &lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;trait FinalActor extends BaseActor[T] {&lt;br /&gt;   lazy val messageHandler = makeMessageHandler()&lt;br /&gt;   override def act() {&lt;br /&gt;       Actor.loop {&lt;br /&gt;          react messageHandler&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;These two classes provide us with a way to compose actors.  We make sure all behavior extends the BaseActor, and we make sure when creating an actor that "FinalActor" gets mixed in *last* in the inheritance linearization.   This means that when FinalActor calls "makeMessageHandler", all the standard OO inheritance has a chance to kick and pull the behaviors you've composed.  Let's see an example of composing an actor with two functionalities....&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;case class Ping()&lt;br /&gt;case class Pong()&lt;br /&gt;&lt;br /&gt;trait PingPongBehavior extends BaseActor {&lt;br /&gt;   def makeMessageHandler() : PartialFunction[Any,Unit] = {&lt;br /&gt;      val myBehavior : PartialFunction[Any,Unit] = {&lt;br /&gt;         case Ping() =&gt; sender ! Pong()&lt;br /&gt;      }&lt;br /&gt;      return myBehavior orElse super.makeMessageHandler()&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is our "PingPong" behavior actor for sending/receiving Ping/Pong messages.   As you can see in the makeMessageHandler... we're manually converting functional composition into inheritance composition.  It does give us flexibility if we'd like our behavior to run last. Let's create our second piece of behavior...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;case class Shutdown()&lt;br /&gt;&lt;br /&gt;trait RemoteControlBehavior extends BaseActor {&lt;br /&gt;   def makeMessageHandler() : PartialFunction[Any,Unit] = {&lt;br /&gt;      val myBehavior : PartialFunction[Any,Unit] = {&lt;br /&gt;         case Shutdown() =&gt; Actor.exit&lt;br /&gt;      }&lt;br /&gt;      return myBehavior orElse super.makeMessageHandler()&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is a simple actor that just lets us send a shutdown command to an actor instead of relying on the actor knowing when to shut itself down (or linking it).  Not necessarily useful, but it will help illustrate our next point.   Let's create an actor that  mixes in both these functionalities.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;val myActor = new PingPongBehavior with RemoteControlBehavior with FinalActor&lt;br /&gt;myActor.start&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice how we *have* to mix in FinalActor last so the composition of makeMessageHandler is done correctly.  This also prevents other actors from adding behavior in their act methods....&lt;br /&gt;&lt;br /&gt;Anyway, it's a decent method of allowing mixin behavior of actors.  It doesn't have much type safety, but the Scala standard actors library actually makes you jump through some hoops to get type-safety anyway (plus all their samples are against Any... so it seems they tend to encourage this...)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now for a look at how Goat-Rodeo helps solve this.   First, Goat-Rodeo uses a type-safe message passing API, including knowing whether a message is allowed a response, and the type of that response.  Let's take a look at a boiled down version of the &lt;a href="https://www.assembla.com/wiki/show/goat_rodeo/Modeling_a_Skitter_User"&gt;twitter-clone sample on goat-rodeo's wiki&lt;/a&gt;.  I've used elipses to ignore implementation details of Goat Rodeo:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;class UserWorker(...) extends WorkerImpl[..., UserMsg](...) {&lt;br /&gt;  /**&lt;br /&gt;   * handle the Follow message&lt;br /&gt;   */&lt;br /&gt;  def doFollow(msg: Follow) {&lt;br /&gt;     ...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, it's just a method.  Goat-Rodeo looks for methods with "do" or "handle" in the name and constructs a PartialFunction for the actor-behavior.   The &lt;pre&gt;Follow&lt;/pre&gt;class must be a subclass of &lt;pre&gt;UserMsg&lt;/pre&gt;as Goat-Rodeo is also strongly typed.  Because &lt;pre&gt;doFollow&lt;/pre&gt;returns Unit, goat-rodeo knows that there is no return expected with this message.  If you'd like to handle different messages, simple use method overloading.  The best part, if we'd like to use OO inheritance to compose behavior, we can do so directly now...&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;class UserWorkerPlus(...) extends UserWorker(...) {&lt;br /&gt;  /**&lt;br /&gt;   * handle the Follow message&lt;br /&gt;   */&lt;br /&gt;  def doFollow(msg: Follow) {&lt;br /&gt;     println("ZOMG!!!!!!!!!!!!!!!!!!")&lt;br /&gt;     super.doFollow(msg)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That should be a lot more comfortable to OO developers.  With some type trickery you could even create the "management" behavior traits and mix them into "workers" as needed.  It still leaves some things to be desired.  e.g. when I compose partial functions in a purely functional sense, I can have the type-checker automatically infer what the new signature of a partial function should be after an orElse.  With both of these methods, that is not possible.  For the pure functional users, I'd recommend creating actors using something akin to this function (or you should just use scalaz, as their actors library is very well done):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;import scala.actors.Actor&lt;br /&gt;import scala.actors.Channel&lt;br /&gt;&lt;br /&gt;class ChanneledActor[T](f : PartialFunction[T,Unit]) extends Actor {&lt;br /&gt;  val typedChannel = new Channel[T](this)&lt;br /&gt;      def act() {&lt;br /&gt;         Actor.loop {&lt;br /&gt;            typedChannel react f&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def makeActor[T, U](f : PartialFunction[T,U]) : Channel[T] = {&lt;br /&gt;   val a = new ChanneledActor(f andThen ( x =&gt; () ))  //Ignore results...&lt;br /&gt;   a.start&lt;br /&gt;   a.typedChannel&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This will let you compose partial functions in a functional style and let the type-checker figure out the signature.  Finally when you create an Actor with the makeActor method, it will return the type-safe channel to send messages with.  Here's an example interpreter session:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;scala&amp;gt; makeActor[Int,Unit] { case x : Int =&gt; println("HAI") }                   &lt;br /&gt;res3: scala.actors.Channel[Int] = scala.actors.Channel@154f77b&lt;br /&gt;&lt;br /&gt;scala&amp;gt; res3 ! "HAI"&lt;br /&gt;&amp;lt;console&amp;gt;:10: error: type mismatch;&lt;br /&gt; found   : java.lang.String("HAI")&lt;br /&gt; required: Int&lt;br /&gt;       res3 ! "HAI"&lt;br /&gt;              ^&lt;br /&gt;&lt;br /&gt;scala&amp;gt; res3 ! 5    &lt;br /&gt;&lt;br /&gt;scala&amp;gt; HAI&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Anyway, if you truly desire a functional approach to actors, you should look into Scalaz, as they've done it right.   If you desire a hybrid or an OO approach, I hope I've helped outline the details for you.   I'm very interested to see how all these libraries evolve over time, and kudos to David Pollak for goat-rodeo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-735483212096690274?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/735483212096690274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=735483212096690274' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/735483212096690274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/735483212096690274'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/02/actor-styles-oo-functional-or-blended.html' title='Actor Styles... OO, Functional or Blended...'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-3838263832103675253</id><published>2010-01-27T21:34:00.000-05:00</published><updated>2010-01-27T21:34:02.792-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='faults'/><title type='text'>Knowing your faults</title><content type='html'>Knowing your faults is great advice.  It's important to know where your own flaws lie, so that you can find ways to work around them.  If you aren't aware of your flaws, you can wind up making some serious mistakes, like letting your emotions make your decisions for you.   &lt;br /&gt;&lt;br /&gt;I think the same can be said of software.   It's important as an engineer to know where your software is weak.  Every project I've ever been on has had at least ten things that "could be improved" if we had more time/money.  Knowing this list is one thing, tracking it and adapting for it is another.&lt;br /&gt;&lt;br /&gt;When designing software, it's important to make sure that the weaknesses aren't critical to the success of your business, however sometimes this is inevitable (or it was designed by someone else ;) ).   Recognizing these flaws lets you mitigate them until you have a chance to remove them.&lt;br /&gt;&lt;br /&gt;In real life, I have a set of close friends who are very honest with me.  If I'm doing something stupid, they'll let me know.   Imagine these friends as my profilers, loggers and monitors.&lt;br /&gt;&lt;br /&gt;There was a recent blog post about &lt;a href="http://feedproxy.google.com/~r/WonderingAround/~3/8Q0NQVEXeys/complement-tdd-with-mda.html"&gt;Monitoring Driven Architecture&lt;/a&gt;.   Finding and determining useful monitoring metrics can be the key differentiated between quickly solving architectural issues and &lt;a href="http://www.youtube.com/watch?v=qg5Rd-Rk4qY"&gt;shooting at the wall hoping you hit your own zombie-infested hand&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In the future, I will not start a new project without identifying weak areas and monitoring points.  These things need to be monitored as soon as possible.  Also, only real deployments can truly tell you which metrics are useful, so make sure you update your monitoring as time goes on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To my readers who still subscribe even though I've been really lame about making useful posts recently:&lt;br /&gt;&lt;br /&gt;I normally don't write these rambling though-stream posts, so send me some feedback.  If you'd rather like more technical blogs, I'm working on a few (The "Leaky" Monad should hopefully be done soon ;) ).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-3838263832103675253?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/3838263832103675253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=3838263832103675253' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/3838263832103675253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/3838263832103675253'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/01/knowing-your-faults.html' title='Knowing your faults'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-2649971606056548528</id><published>2010-01-20T20:39:00.001-05:00</published><updated>2010-01-20T20:41:50.579-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='slave'/><category scheme='http://www.blogger.com/atom/ns#' term='hudson'/><category scheme='http://www.blogger.com/atom/ns#' term='init.d'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='agent'/><title type='text'>Hudson Slave agent startup script</title><content type='html'>Last night, I got really annoyed at our hudson build slaves not automatically starting on our build nodes.  I found a few init.d scripts online, and I pieced this one together with some additional functionality.&lt;br /&gt;&lt;br /&gt;Still needs a bit more features, specifically:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ability to run as hudson user or root user&lt;/li&gt;&lt;li&gt;Ability to change hudson port&lt;/li&gt;&lt;li&gt;Ability to have different Credentials&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Anyway, I hope others find this helpful.  It's meant to be run on a hudson build node to automatically connect to hudson at startup.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre&gt;#!/bin/bash&lt;br /&gt;#&lt;br /&gt;# Init file for hudson server daemon&lt;br /&gt;#&lt;br /&gt;# chkconfig: 2345 65 15&lt;br /&gt;# description: Hudson slave&lt;br /&gt;&lt;br /&gt;. /etc/rc.d/init.d/functions&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;RETVAL=0&lt;br /&gt;NODE_NAME="centos-executor"&lt;br /&gt;HUDSON_HOST=1.2.3.4&lt;br /&gt;USER=hudson&lt;br /&gt;&lt;br /&gt;pid_of_hudson() {&lt;br /&gt;   ps auxwww | grep java | grep hudson | grep -v grep | awk '{ print $2 }'&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;start() {&lt;br /&gt;        if [ ! -e /var/log/hudson ]; then&lt;br /&gt;  touch /var/log/hudson&lt;br /&gt;  chown $USER /var/log/hudson&lt;br /&gt; fi&lt;br /&gt;        echo -n $"Starting hudson: "&lt;br /&gt;        COMMAND="java -jar /opt/hudson/slave.jar -jnlpUrl http://${HUDSON_HOST}/hudson/computer/${NODE_NAME}/slave-agent.jnlp 2&gt;/var/log/hudson.err &gt;/var/log/hudson"&lt;br /&gt;        su ${USER} -c "$COMMAND" &amp;&lt;br /&gt;        sleep 1&lt;br /&gt;        pid_of_hudson &gt; /dev/null&lt;br /&gt;        RETVAL=$?&lt;br /&gt;        [ $RETVAL = 0 ] &amp;&amp; success || failure&lt;br /&gt;        echo&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;stop() {&lt;br /&gt;        echo -n "Stopping hudson slave: "&lt;br /&gt;        pid=`pid_of_hudson`&lt;br /&gt;        [ -n "$pid" ] &amp;&amp; kill $pid&lt;br /&gt;        RETVAL=$?&lt;br /&gt;        cnt=10&lt;br /&gt;        while [ $RETVAL = 0 -a $cnt -gt 0 ] &amp;&amp;&lt;br /&gt;                { pid_of_hudson &gt; /dev/null ; } ; do&lt;br /&gt;                        sleep 1&lt;br /&gt;                ((cnt--))&lt;br /&gt;        done&lt;br /&gt;&lt;br /&gt;        [ $RETVAL = 0 ] &amp;&amp; success || failure&lt;br /&gt;        echo&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;status() {&lt;br /&gt;        pid=`pid_of_hudson`&lt;br /&gt;        if [ -n "$pid" ]; then&lt;br /&gt;                echo "hudson (pid $pid) is running..."&lt;br /&gt;                return 0&lt;br /&gt;        fi&lt;br /&gt;        echo "hudson is stopped"&lt;br /&gt;        return 3&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#Switch on called&lt;br /&gt;case "$1" in&lt;br /&gt;  start)&lt;br /&gt;        start&lt;br /&gt;        ;;&lt;br /&gt;  stop)&lt;br /&gt;        stop&lt;br /&gt;        ;;&lt;br /&gt;  status)&lt;br /&gt;        status&lt;br /&gt;        ;;&lt;br /&gt;  restart)&lt;br /&gt;        stop&lt;br /&gt;        start&lt;br /&gt;        ;;&lt;br /&gt;  *)&lt;br /&gt;        echo $"Usage: $0 (start|stop|restart|status}"&lt;br /&gt;        exit 1&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;exit $RETVAL&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-2649971606056548528?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/2649971606056548528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=2649971606056548528' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2649971606056548528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2649971606056548528'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/01/hudson-slave-agent-startup-script.html' title='Hudson Slave agent startup script'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-6070835290560715751</id><published>2010-01-13T16:18:00.000-05:00</published><updated>2010-01-13T16:18:25.588-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Too Busy</title><content type='html'>I've been crazy busy between work and writing a book.  I have been writing a few blogs for the company, the first of which is complete, if you'd like to &lt;a href="http://fortisphere.com/in-the-news/blogs.stml?portalProcess_dd_0_3=showPublicPosting&amp;calendar_entry_id=2811"&gt;view it&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can also see advertisements for my upcoming book (name misspelled, yay) on &lt;a href="http://www.manning.com/catalog/undercontract.html"&gt;Manning's under contract page.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6070835290560715751?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6070835290560715751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6070835290560715751' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6070835290560715751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6070835290560715751'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2010/01/too-busy.html' title='Too Busy'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-2253809788902354980</id><published>2009-11-10T19:18:00.000-05:00</published><updated>2009-11-10T19:18:11.614-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Using Maven to Develop Scala</title><content type='html'>Here's my presentation for the Scala LiftOff (East Coast) Conference.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://docs.google.com/present/embed?id=dfqn4jb_64fsd3dfcn&amp;interval=5&amp;size=m" frameborder="0" width="555" height="451"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-2253809788902354980?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/2253809788902354980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=2253809788902354980' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2253809788902354980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2253809788902354980'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/11/using-maven-to-develop-scala.html' title='Using Maven to Develop Scala'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-5977271896792293087</id><published>2009-09-02T23:35:00.004-04:00</published><updated>2009-09-14T21:40:17.444-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='dogfood'/><title type='text'>The cost of dogfood.... (or brocolli)</title><content type='html'>So, I've been busy lately.  My blog has suffered.  I apologize guys.  Pretty soon I'll post yet another rant against EJB.  Honestly, I feel people who love EJB have not used it extensively, or have only programmed in Java.&lt;br /&gt;&lt;br /&gt;Anyway, I've been trying to help blog at work, and wrote an article you can find on our company website &lt;a href="http://fortisphere.com/blogs/the-cost-of-dog-food-in-the-cloud/"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-5977271896792293087?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/5977271896792293087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=5977271896792293087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5977271896792293087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5977271896792293087'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/09/cost-of-dogfood-or-brocolli.html' title='The cost of dogfood.... (or brocolli)'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-437119369663869735</id><published>2009-08-17T18:14:00.004-04:00</published><updated>2009-08-19T09:31:41.781-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='application'/><category scheme='http://www.blogger.com/atom/ns#' term='optional.'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Avoid the Applicaiton trait in Scala</title><content type='html'>All, It's been a *long* time since I've been writing this blog.  Today I felt I'd try for a very short article.&lt;br /&gt;&lt;br /&gt;It seems to me that about every 2 weeks, someone comes on the Scala #irc or mailing lists and asks about performance issues.  It also appears there is no end to people who want to use Scala's Application trait.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do not be so tempted.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The application trait is a very neat feat of scala-mojo for automagically creating a main method, however it has one serious flaw: &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Your entire application is run inside a static initializer block.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This having another serious flaw:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hotspot will not optimize your application.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Anyone who wishes to have a real "scala" application like trait and doesn't want to write an ugly &lt;pre&gt;def main(args : Array[String]) : Unit = {}&lt;/pre&gt; should run down to their local github and look at DRMacIver's &lt;a href="http://github.com/DRMacIver/optional/tree/master"&gt;Optional&lt;/a&gt; library.&lt;br /&gt;&lt;br /&gt;&lt;i&gt; Update:  You should look at paulp's &lt;a href="http://github.com/paulp/optional/tree/master"&gt;github fork of optional&lt;/a&gt;.  I was unaware of this before I wrote the blog article.  I've modified appropriately&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;You still have to write a main method, but this team the arguments *mean* something, not just to the compiler, but to the command line!&lt;br /&gt;&lt;br /&gt;Here's the readme from paulp's Optional repo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;optional is a command line option parser and library.&lt;br /&gt;&lt;br /&gt;YOU WRITE:&lt;br /&gt;&lt;br /&gt;object MyAwesomeCommandLineTool extends optional.Application {&lt;br /&gt;  // for instance...&lt;br /&gt;  def main(count: Option[Int], file: Option[java.io.File], arg1: String) {&lt;br /&gt;    [...]&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;THEN YOU DO:&lt;br /&gt;&lt;br /&gt;  scala MyAwesomeCommandLineTool --count 5 quux&lt;br /&gt;&lt;br /&gt;AND YOUR MAIN METHOD WILL BE INVOKED SUCH THAT:&lt;br /&gt;&lt;br /&gt;  count = Some(5)&lt;br /&gt;  file = None&lt;br /&gt;  arg1 = quux&lt;br /&gt;  &lt;br /&gt;See the example programs for many more features.&lt;br /&gt;&lt;br /&gt;HOW IT WORKS:&lt;br /&gt;&lt;br /&gt;  Reflection, man.&lt;br /&gt;&lt;br /&gt;CREDITS:&lt;br /&gt;&lt;br /&gt;  Idea and prototype implementation: DRMacIver.&lt;br /&gt;   Fleshing out and awesomification: paulp.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In Other news&lt;br /&gt;&lt;br /&gt;I've recently been doing a bit of Scala + EJB and (funny enough) PowerShell scripting.   Hopefully I'll have good things to write about and (more importantly) the time to do so in the near future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-437119369663869735?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/437119369663869735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=437119369663869735' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/437119369663869735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/437119369663869735'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/08/avoid-applicaiton-trait-in-scala.html' title='Avoid the Applicaiton trait in Scala'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-1067446663792827453</id><published>2009-06-12T20:14:00.008-04:00</published><updated>2009-06-13T10:33:23.102-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='ARM'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='project coin'/><category scheme='http://www.blogger.com/atom/ns#' term='RRID'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Why ARM is not quite enough</title><content type='html'>This post is for you project coin!   I would rather not see any ARM in the Java language, than a subdued ARM (ARM = Automated Resource Management).   Here's why:&lt;br /&gt;&lt;br /&gt;ARM is trying to solve the age old problem of ensuring closure of resources when finished with your business logic.  In C++ we would use RRID (Resource Release Is Destruction) to accomplish this.  e.g.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;class LockEnforcer : public boost::noncopyable&amp;lt;LockEnforcer&amp;gt;{&lt;br /&gt;     T&amp; lock;&lt;br /&gt;&lt;br /&gt;  public:&lt;br /&gt;      LockEnforcer(T&amp; lock) : lock(lock) { lock.lock(); }&lt;br /&gt;      ~LockEnforcer() { lock.unlock(); }      &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//Later in a method....&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;   LockEnforcer(someLock);&lt;br /&gt;&lt;br /&gt;   //Do my business logic&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;//Lock is shut down here by nature of Destruction&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This suffered from a few problems:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt; Destructors should not throw exceptions! (Read Effective C++).  This could leave you in a dangerous state potentially if you cared whether or not "close" threw some exception.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt; The destruction behavior ALWAYS happens.  If you wanted to change whether or not cleanup occurs, you have to put state into the class and some more complex logic in the destructor.  You also need to make calls on the class to inform it *not* to do the usually cleanup.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Java steps in lacking destructors, and forces developers to take a new paradigm.  Let's look at a typical Java JDBC connection usage paradigm.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;Connection conn = null;&lt;br /&gt;try {&lt;br /&gt;   conn = getConnection();&lt;br /&gt;   //Business Logic&lt;br /&gt;} finally {&lt;br /&gt;    try {&lt;br /&gt;        if(conn != null) {&lt;br /&gt;            conn.close();&lt;br /&gt;        }&lt;br /&gt;    } catch(SQLException e) {&lt;br /&gt;       //Ignore - that way if we already had an exception, we don't lose it on close.&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now, I have potentially buggy code everywhere I need to use connections.  I'm also not able to re-use code easily.  Now, the Spring framework truly does solve this problem (see any of the *Template classes), but we'll get to how and why it's useful later.  For now, assume we're stuck with pure java (or we're in a domain that isn't covered by Spring yet).  Coin proposes the following ARM syntax:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;try (Connection conn = getConnection()) {&lt;br /&gt;   &lt;br /&gt;   //Business Logic&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This would be equivalent to the above block.  It is much nicer, and certain helps in the general case of resource management.  Using multiple resources would of course imply multiple try blocks.&lt;br /&gt;&lt;br /&gt;The problem is that this doesn't solve the more general problem.  The general problem is that you have code that is duplicated across several methods.  This code needs to run before and after some non-duplicated section.  Take for example the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;try  {&lt;br /&gt;  if(isNewMessage(msg)) {&lt;br /&gt;        handleMessage(msg);&lt;br /&gt;  }&lt;br /&gt;  sendMessageAcknowledgement(msg); //Note this is *not* in the finally&lt;br /&gt;} catch (Exception e) {&lt;br /&gt;  //Do something with exceptions&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I'm unable to use ARM because I want the final code (before the catch) to be run if the above code passes without exception.  The other problem here is that I have 5 methods with this same boiler-plate (except same isNewMessage function), and different handleMessage functions.  Typically, Java encourages you to create a base class, with abstract handleMessage.  Then you extend classes with different handleMessages.  That's pretty much the only way to reuse code here.  What if I don't really want other classes?&lt;br /&gt;&lt;br /&gt;Well, Scala comes to the rescue (slightly).  Scala will let me write the above code using functional composition, and behind the scenes it's desugaring to multiple classes that inherit the "Function" interface.  &lt;br /&gt;&lt;i&gt;Note: That the Spring *Template classes take this approach, only with less generic interfaces.  Instead of "Function1", it's SqlRowMapper.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Here's an example in scala.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//Helper function&lt;br /&gt;def processMessage(msg : Msg)(handlerFunction : Msg =&gt; Unit) = {&lt;br /&gt;   try {&lt;br /&gt;      if(isNewMessage(msg) {&lt;br /&gt;           handlerFunction(msg)&lt;br /&gt;      }&lt;br /&gt;      sendAcknowledgement(msg)&lt;br /&gt;   } catch {&lt;br /&gt;           case e =&gt; //TODO - Handle&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//My actual method&lt;br /&gt;processMessage(msg) { &lt;br /&gt;   msg =&gt;&lt;br /&gt;       //Business Logic&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you can see, I've removed duplicate code, and without a lot of boilerplate.   ARM would not be necessary if Java had closures, and the entire set of problems (not just resource management) revolving around repeated code at start/end of blocks would also be solved.   Personally, I would rather just wait for Java to have closures.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-1067446663792827453?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/1067446663792827453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=1067446663792827453' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1067446663792827453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1067446663792827453'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/06/why-arm-is-not-quite-enough.html' title='Why ARM is not quite enough'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-4357078624248739798</id><published>2009-05-18T21:23:00.003-04:00</published><updated>2009-05-18T21:38:24.935-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java.jigsaw'/><title type='text'>Demo Oriented Programming (and Project Jigsaw)</title><content type='html'>So recently I've been amused watching the OpenJDK Jigsaw project mailing list.  Basically there have been a few emails that look like the following:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;   &lt;li&gt; I have this working in this way.  It has these flaws.  I'd like to ignore them so we can finish in time for JavaONE&lt;/li&gt;&lt;br /&gt;   &lt;li&gt; Sounds good &lt;/li&gt;&lt;br /&gt;   &lt;li&gt; I have an even bigger hack I'd like to introduct temporarily for JavaONE, it will make the demo run smoothly, just don't use Windows or Mac&lt;/li&gt;&lt;br /&gt;   &lt;li&gt; Ok, but make sure you fix it after JavaONE&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;The fun part about "open" source is that this kind of back-and-forth is just that: open.  Things that every company does for demos is now public domain and I can create a &lt;a href="http://mail.openjdk.java.net/pipermail/jigsaw-dev/2009-May/000138.html"&gt;link showing one of the conversations&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;We've all had times in development where you need to push some hacks through to get something done in time for a demo.  The key is to cleanup your code afterwords and make sure that it's ready for production in time.  This is where powerpoint can be your friend and your enemy.  It is great to *show* people what you mean, but sometimes they need to get the feel of it to really see what it is you want to do.  That's why I believe wholeheartily in Demo-Oriented programming.  Get something out there that looks enough like the real thing so your users can complain about it.  Until you hand them something that they can use, you won't get very articulate/useful feedback.&lt;br /&gt;&lt;br /&gt;However, Demo-Oriented Programming relies heavily on the ability to refactor quickly and/or rewrite sections of code.  You need a good management chain that will allow you to take the time and fix "demo-related" items in time for actual release.  This means you can get good intiial feedback, and continuing good feedback from users.  I definitely see Sun as being a great DOP shop.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On a slightly unrelated note, it looks like project-jigsaw is really coming along.  I'm still very unsure if packaging modules "natively" (i.e. rpm, deb, etc) is the right approach, but at least some of the underlying "jvm bootstrap" issues appear to be getting some attention.  I'm also *very* curious to see what happens with jigsaw + OSGi.  I do not see a lot of mention of OSGi from the jigsaw-dev lists, but I see lots of investment in OSGi from other companies, and a lot of strength in the platform.  I would not use EJB anymore (by choice) and I believe an OSGi runtime + carefully chosen libraries will be my new "enterprise application server stack".  Hopefully jigsaw will not slow down the momentum of the OSGi community.  I'm very much looking forward to being able to choose which orthogonal, cross-cutting "concerns" I want in my application.  Perhaps just transactions and scalability?  Maybe I like terracotta.  Maybe I need something more custom?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-4357078624248739798?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/4357078624248739798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=4357078624248739798' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/4357078624248739798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/4357078624248739798'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/05/demo-oriented-programming-and-project.html' title='Demo Oriented Programming (and Project Jigsaw)'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-6128626517916957035</id><published>2009-04-28T21:39:00.006-04:00</published><updated>2009-04-30T09:44:07.784-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interpreter'/><category scheme='http://www.blogger.com/atom/ns#' term='embed'/><category scheme='http://www.blogger.com/atom/ns#' term='dsl'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Embedding the Scala Interpreter</title><content type='html'>Recently, I was given an application at work that needed some extra functionality, and basically needed to be made more flexible.  As this is an internal tool, it currently requires 'expert' usage only.  Thinking through the design, I decided that perhaps I should try an idea I've heard others use:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Let's write the configuration for the application in a Scala Domain Specific Language.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;To do so, I need to make the application "modular" in the sense that various components can be configured through some sort of "builder" pattern DSL.  They are then assembled together (again in a DSL), which should be as readable as possible, and easy to change.  The DSL creation went great, the app is looking good.  Here's a pseudo example of what I'm talking about.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;val input = new InputChannel with ReconnectOnFailure {&lt;br /&gt;    inputUrl = "http://suereth.blogspot.com"&lt;br /&gt;}&lt;br /&gt;val output = new OutputChannel with FileWriter {&lt;br /&gt;   outputUrl = "file:///home/josh/test.out"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;processingBuilder from input to output and { p =&amp;gt;&lt;br /&gt;      p hasModule new ThemeExtractor {&lt;br /&gt;           maxThemes = 10&lt;br /&gt;           //Define more variables&lt;br /&gt;      }&lt;br /&gt;      //Define more modules       &lt;br /&gt;}&lt;br /&gt;processingBuilder.startProcess()&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The above is a hypothetical DSL for processing inputs and placing the results in an output.  The idea being you can generate "filter chains" via the processingBuilder object.  Ideally, this configuration should be in some kind of file we can pass into our program, rather than having to recompile the program every time we want to run.  Imagine however, that we combine these two solutions.&lt;br /&gt;&lt;br /&gt;Let's compile the DSL and all the internals of the program and place them into a jar file.  Let's then take the "configuration" portion of the program and compile it at runtime, just before execution.  To do this, we can simply embed the Scala interpreter.  I'm going to make use of an open-source "library" (really just one class) I wrote one evening while testing this theory.  The library (&lt;a href="http://github.com/jsuereth/scala-embedded-interpreter-sample/tree/master"&gt;Scala Embedded Interpreter&lt;/a&gt;) is located on github and is BSD licensed.&lt;br /&gt;&lt;br /&gt;To start off with, we need some kind of main class that will take a "configuration" file as an argument, and pass it into our embedded interpreter.  Let's try something like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;object App {&lt;br /&gt;   def main(args : Array[String]) {&lt;br /&gt;        //Let's assume all arguments are file locations for configuration&lt;br /&gt;&lt;br /&gt;        val interpreter = new InterpreterWrapper {&lt;br /&gt;            for(fileName &lt;- args) {&lt;br /&gt;              addScriptFile(fileName)&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        interpreter.startInterpreting()&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So, the above is fairly simple.  We construct and InterpreterWrapper and call "addScriptFile" for every configuration file we find on our command line.  So... how is InterpreterWrapper working?  Let's look into the details:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;import scala.tools.nsc._&lt;br /&gt;import interpreter._&lt;br /&gt;import java.io._&lt;br /&gt;import scala.reflect._&lt;br /&gt;/**&lt;br /&gt; * A trait to ease the embedding of the scala interpreter&lt;br /&gt; */&lt;br /&gt;trait InterpreterWrapper {&lt;br /&gt;  private var files = List[String]()&lt;br /&gt;  ...&lt;br /&gt;  protected def addScriptFile(fileName : String) {&lt;br /&gt;    files = fileName :: files&lt;br /&gt;  }&lt;br /&gt;  ...&lt;br /&gt;  def startInterpreting() {&lt;br /&gt;    //Make a place for output to go&lt;br /&gt;    val out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)))&lt;br /&gt;    //Create a new Interpreter settings object with the given output method&lt;br /&gt;    val settings = new GenericRunnerSettings(out.println _)&lt;br /&gt;    //For every file, add it to the interpreter settings&lt;br /&gt;    files.foreach(settings.loadfiles.appendToValue)&lt;br /&gt;    &lt;br /&gt;    //Create a new interpreter loop and start running!&lt;br /&gt;    val interpreter = new InterpreterLoop(out)&lt;br /&gt;    interpreter.main(settings)&lt;br /&gt;    ()&lt;br /&gt;  }&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see, the trait is fairly simple.  It creates a "Settings" object (which is normally created by parsing off the command line arguments) and passes it into "InterpreterLoop".  InterpreterLoop is the class which wraps "Interpreter" by continually prompting and executing input.  This allows us to do live configuration of our program (which can be very fun).&lt;br /&gt;&lt;br /&gt;The next thing we need to do is promote our DSL into the interpreter, so our configuration files don't begin with unnecessary "import foo.bar._" statements.  Let's modify our App and the InterpreterWrapper.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;object App {&lt;br /&gt;   def main(args : Array[String]) {&lt;br /&gt;        //Let's assume all arguments are file locations for configuration&lt;br /&gt;&lt;br /&gt;        val interpreter = new InterpreterWrapper {&lt;br /&gt;            autoImport("my.awesome.dsl._")&lt;br /&gt;&lt;br /&gt;            for(fileName &amp;lt;- args) {&lt;br /&gt;              addScriptFile(fileName)&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        interpreter.startInterpreting()&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So the main code doesn't change much, simply adding the "autoImport" method call when constructing the InterpreterWrapper.   However, we now need to some more magic in the interpreter wrapper.  Here's the (relevant portions of the) code:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;import scala.tools.nsc._&lt;br /&gt;import interpreter._&lt;br /&gt;import java.io._&lt;br /&gt;import scala.reflect._&lt;br /&gt;&lt;br /&gt;trait InterpreterWrapper {&lt;br /&gt;&lt;br /&gt;  private var packageImports : List[String] = List()  &lt;br /&gt;  &lt;br /&gt;  protected def autoImport(importString : String) {&lt;br /&gt;    packageImports = importString :: packageImports&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * This class actually runs the interpreter loop.&lt;br /&gt;   */&lt;br /&gt;  class MyInterpreterLoop(out : PrintWriter) extends InterpreterLoop(None, out) {    &lt;br /&gt;    &lt;br /&gt;     override def bindSettings() {       &lt;br /&gt;       super.bindSettings()      &lt;br /&gt;       interpreter beQuietDuring {&lt;br /&gt;         //This will silently execute our import statements when starting!&lt;br /&gt;         for( importString &amp;lt;- packageImports) {&lt;br /&gt;          interpreter.interpret("import " + importString)&lt;br /&gt;         } &lt;br /&gt;       }&lt;br /&gt;     }   &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  def startInterpreting() {&lt;br /&gt;    val out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)))&lt;br /&gt;    val settings = new GenericRunnerSettings(out.println _)&lt;br /&gt;    ...&lt;br /&gt;    val interpreter = new MyInterpreterLoop(out)&lt;br /&gt;    interpreter.main(settings)&lt;br /&gt;    ()&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see, we're using a subclass of MyInterpreterLoop and extending the "bindSettings" method to additionally execute our import statements.  We can now almost use our DSL directly.  The only remaining issue is that we'd like to have our processingBuilder object be automatically bound and in scope for the interpreter session.  This allows the configuration to just start directly talking with the object.   Let's add "bind" functionality to the InterpreterWrapper with the following API:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;object App {&lt;br /&gt;   def main(args : Array[String]) {&lt;br /&gt;        //Let's assume all arguments are file locations for configuration&lt;br /&gt;&lt;br /&gt;        val interpreter = new InterpreterWrapper {&lt;br /&gt;            autoImport("my.awesome.dsl._")&lt;br /&gt;            bind("processingBuilder", new MyProcessingBuilderImplementationClass())&lt;br /&gt;            //OR if I want to restrict access to an interface&lt;br /&gt;            bindAs("processingBuilder2", classOf[ProcessingBuilder], new MyProcessingBuilderImplementationClass())&lt;br /&gt;            for(fileName &amp;lt;- args) {&lt;br /&gt;              addScriptFile(fileName)&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        interpreter.startInterpreting()&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;We now need to update the InterpreterWrapper.  We'll be doing a similar trick as autoImport and adding some "silent" execution during the bindSettings method of InterpreterLoop.  Here's the relevant code:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;trait InterpreterWrapper {&lt;br /&gt;  ...&lt;br /&gt;  private var bindings : Map[String, (java.lang.Class[_], AnyRef)] = Map()&lt;br /&gt;  ...&lt;br /&gt;  protected def bind[A &amp;lt;: AnyRef](name : String, value : A)(implicit m : Manifest[A]) {&lt;br /&gt;    bindings +=  (( name,  (m.erasure, value)))&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected def bindAs[A &amp;lt;: AnyRef, B &amp;lt;: A](name : String, interface : java.lang.Class[A], value : B) {&lt;br /&gt;    bindings += ((name,  (interface, value)))&lt;br /&gt;  }&lt;br /&gt;  ...  &lt;br /&gt;  class MyInterpreterLoop(out : PrintWriter) extends InterpreterLoop(None, out) {&lt;br /&gt;    &lt;br /&gt;     override def bindSettings() {       &lt;br /&gt;       super.bindSettings()      &lt;br /&gt;       interpreter beQuietDuring {&lt;br /&gt;         for( (name, (clazz, value)) &amp;lt;- bindings) {&lt;br /&gt;           interpreter.bind(name, clazz.getCanonicalName, value)&lt;br /&gt;         }&lt;br /&gt;         ... //auto-imports&lt;br /&gt;       }&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  def startInterpreting() {&lt;br /&gt;    ...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here we're using the "bind" method of the underlying Interpreter object.  This allows us to bind arbitrary objects and specify their interface.  For the InterpreterWrapper we've two bind methods, one which uses the experimental Manifest feature of scala to automatically use the visible type at the bind call, and another method where you can explicitly specify a type.&lt;br /&gt;&lt;br /&gt;We now have our configuration file being loaded and executed in a nice convenient DSL.  The last bit we should do is "brand" the interpreter, so that it looks like we intend to use it (and not like scala suddenly shows up in our app).  To do so we're going to override the help message, the welcome message and the prompt.  Here's what our main object should look like:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;object App {&lt;br /&gt;   def main(args : Array[String]) {&lt;br /&gt;        //Let's assume all arguments are file locations for configuration&lt;br /&gt;&lt;br /&gt;        val interpreter = new InterpreterWrapper {&lt;br /&gt;            def prompt = "Processor&amp;gt; "&lt;br /&gt;            def welcomeMsg = "Welcome to the InterWeb Text Processing Magician! Please set up a processing stream to be executed."&lt;br /&gt;            def helpMsg = "To set up a processing stream, please create an input and output and wire them together using the processingBuilder.  :help will print this message, :quit will exit the processor"&lt;br /&gt;&lt;br /&gt;            autoImport("my.awesome.dsl._")&lt;br /&gt;            bind("processingBuilder", new MyProcessingBuilderImplementationClass())&lt;br /&gt;            //OR if I want to restrict access to an interface&lt;br /&gt;            bindAs("processingBuilder2", classOf[ProcessingBuilder], new MyProcessingBuilderImplementationClass())&lt;br /&gt;            for(fileName &amp;lt;- args) {&lt;br /&gt;              addScriptFile(fileName)&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        interpreter.startInterpreting()&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see, using the InterpreterWrapper allows you to quickly and easily embed the scala interpreter and use it to configure your application (at start up or during execution).  Remember, though, that as with an user-interface you need to worry about threading issues when attempting to run concurrent threads (or use actors).&lt;br /&gt;&lt;br /&gt;Finally, here's the entire code for the InterpreterWrapper (under BSD license BTW):&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;import scala.tools.nsc._&lt;br /&gt;import interpreter._&lt;br /&gt;import java.io._&lt;br /&gt;import scala.reflect._&lt;br /&gt;/**&lt;br /&gt; * A trait to ease the embedding of the scala interpreter&lt;br /&gt; */&lt;br /&gt;trait InterpreterWrapper {&lt;br /&gt;&lt;br /&gt;  private var bindings : Map[String, (java.lang.Class[_], AnyRef)] = Map()&lt;br /&gt;  private var packageImports : List[String] = List()  &lt;br /&gt;  private var files = List[String]()&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Binds a given value into the interpreter when it starts with its most specific class&lt;br /&gt;   */&lt;br /&gt;  protected def bind[A &amp;lt;: AnyRef](name : String, value : A)(implicit m : Manifest[A]) {&lt;br /&gt;    bindings +=  (( name,  (m.erasure, value)))&lt;br /&gt;  }&lt;br /&gt;  /**&lt;br /&gt;   * Binds a given value itnot he interpreter with a given interface/higher-level class.&lt;br /&gt;   */&lt;br /&gt;  protected def bindAs[A &amp;lt;: AnyRef, B &amp;lt;: A](name : String, interface : java.lang.Class[A], value : B) {&lt;br /&gt;    bindings += ((name,  (interface, value)))&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * adds an auto-import for the interpreter.&lt;br /&gt;   */&lt;br /&gt;  protected def autoImport(importString : String) {&lt;br /&gt;    packageImports = importString :: packageImports&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * Adds a file that will be interpreter at the start of the interpreter&lt;br /&gt;   */&lt;br /&gt;  protected def addScriptFile(fileName : String) {&lt;br /&gt;    files = fileName :: files&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  def helpMsg : String&lt;br /&gt;  def welcomeMsg : String&lt;br /&gt;  def prompt : String&lt;br /&gt;  &lt;br /&gt;  /**&lt;br /&gt;   * This class actually runs the interpreter loop.&lt;br /&gt;   */&lt;br /&gt;  class MyInterpreterLoop(out : PrintWriter) extends InterpreterLoop(None, out) {&lt;br /&gt;     override val prompt = InterpreterWrapper.this.prompt&lt;br /&gt;    &lt;br /&gt;     override def bindSettings() {       &lt;br /&gt;       super.bindSettings()      &lt;br /&gt;       interpreter beQuietDuring {&lt;br /&gt;         for( (name, (clazz, value)) &amp;lt;- bindings) {&lt;br /&gt;           interpreter.bind(name, clazz.getCanonicalName, value)&lt;br /&gt;         }&lt;br /&gt;         for( importString &lt;- packageImports) {&lt;br /&gt;          interpreter.interpret("import " + importString)&lt;br /&gt;         } &lt;br /&gt;       }&lt;br /&gt;     }&lt;br /&gt;    override def printHelp {&lt;br /&gt;       printWelcome()&lt;br /&gt;       out.println(helpMsg)&lt;br /&gt;       out.flush()&lt;br /&gt;     }&lt;br /&gt;     &lt;br /&gt;     override def printWelcome() {&lt;br /&gt;       out.println(welcomeMsg)&lt;br /&gt;       out.flush()&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  def startInterpreting() {&lt;br /&gt;    val out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)))&lt;br /&gt;    val settings = new GenericRunnerSettings(out.println _)&lt;br /&gt;    files.foreach(settings.loadfiles.appendToValue)&lt;br /&gt;    //Below for 2.8.0-SNAPSHOT&lt;br /&gt;    //settings.completion.value = true&lt;br /&gt;    &lt;br /&gt;    val interpreter = new MyInterpreterLoop(out)&lt;br /&gt;    interpreter.main(settings)&lt;br /&gt;    ()&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I must say, I'm very happy with how my project turned out at work.  It actually made things *much* easier to debug during development as I could interact directly with the program during execution.  The only complaint so far from co-workers is that they don't know enough Scala to used some of the more advanced features (for-expressions actually).  However, the sample configurations I provided were enough for them to get up and running with the application and create slightly varied configurations.  We have slightly more verbosity in configuration now, but the flexibility/power is incredible.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Below is the output of the exeuction of my very silly "test" usage of the InterpreterWrapper (included in the github project).  This sample is using Scala 2.8.0 nightly and Paul Phillips&lt;a href="http://en.wikipedia.org/wiki/Apostrophe_(mark)#Singular_nouns_ending_with_an_.22s.22_or_.22z.22_sound"&gt;'s&lt;/a&gt; interpreter improvements.  You can see the auto-complete suggestions below.  &lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;br /&gt;josh@suereth-desktop:~/projects/blog/embed-the-interpreter$ java -jar target/embedded-interpreter-0.1-SNAPSHOT-jar-with-dependencies.jar &lt;br /&gt;Welcome to Awesomeness!&lt;br /&gt;This is my version of the Scala interpreter&lt;br /&gt;TestInterpreter&amp;gt; j&lt;br /&gt;&lt;br /&gt;java    javax   jline&lt;br /&gt;TestInterpreter&amp;gt; j&lt;br /&gt;&lt;br /&gt;java    javax   jline&lt;br /&gt;TestInterpreter&amp;gt; josh.is&lt;br /&gt;res0: java.lang.String = Brillant!!!&lt;br /&gt;TestInterpreter&amp;gt; josh.&lt;br /&gt;&lt;br /&gt;getClass   is         name       toString&lt;br /&gt;TestInterpreter&amp;gt; josh.&lt;br /&gt;&lt;br /&gt;getClass   is         name       toString&lt;br /&gt;TestInterpreter&amp;gt; josh.name&lt;br /&gt;res3: String = josh&lt;br /&gt;TestInterpreter&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6128626517916957035?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6128626517916957035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6128626517916957035' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6128626517916957035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6128626517916957035'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/04/embedding-scala-interpreter.html' title='Embedding the Scala Interpreter'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-7953146759790388602</id><published>2009-04-13T22:33:00.010-04:00</published><updated>2009-04-14T19:55:44.493-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='inheritance'/><category scheme='http://www.blogger.com/atom/ns#' term='partial functions'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Partial Functions + Inheritance</title><content type='html'>Recently, I've been doing more work with Scala actors, and a particular problem arose with attempting to define 'abstract' actors and extend them with traits.  My goal was to implement something like the "chain of command" pattern, but using partial functions and messages.  To demonstrate, imagine the following system:&lt;br /&gt;&lt;br /&gt;We're going to simulate network traffic on a machine.  A machine may have any number of servers on it, each of which can attempt to handle an incoming network connection.   Let's picture an web server process on that server.  Let's take a first cut at modeling a "network daemon" in Scala.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;trait NetworkMessage //This would be some complex object&lt;br /&gt;import scala.actors.Actor&lt;br /&gt;import Actor._&lt;br /&gt;trait NetworkDaemon extends Actor {&lt;br /&gt;   def trafficHandlers : PartialFunction[Any,Unit]&lt;br /&gt;   def act() {&lt;br /&gt;       loop(react(trafficHandlers))&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So why not just create the partial function for react inline?  Why have a separate method that defines the function?  Remember, we're trying to implement a chain of command pattern with our actor.  This means our subclasses need to attempt to handle message first, and defer to us if unable.  The main reason to use a "method returning a partial function" vs. actually method overriding/extending is so that we preserve the partial-function's "isDefinedAt" semantics.  Because we're using actors, it is beneficial if our "handler" function does *not* work against all input, but allows things to pass through.   This helps us not catch internal actors communication *and* allow things like linking actors together.&lt;br /&gt;&lt;br /&gt;Now, let's start with modeling a web server that hosts static content.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//Extractor for staticly served content&lt;br /&gt;object HttpRequestForStaticResource {&lt;br /&gt;   def unapply(msg : Any) : Option[StaticResource] = None //TODO - Implement&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//WebServer basic model&lt;br /&gt;trait WebServer extends NetworkDaemon {&lt;br /&gt;   def trafficHandlers : PartialFunction[Any,Unit] = {&lt;br /&gt;      case HttpRequestForStaticResource(resource) =&gt; reply(resource.getContents)&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now imagine we want two types of web servers, a 'static' server that *always* server static content, and a subclass of that which can also proxy connections to other web servers.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//Define a new extractor for proxying&lt;br /&gt;object ProxyableConnection {&lt;br /&gt;   def unapply(...)...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//WebServer basic model&lt;br /&gt;trait ProxyWebServer extends WebServer {&lt;br /&gt;&lt;br /&gt;   def trafficHandlers : PartialFunction[Any,Unit] = {&lt;br /&gt;       val myHandlers : PartialFunction[Any,Unit] = {&lt;br /&gt;             case ProxyableConnection(...) =&gt; forward(...)&lt;br /&gt;       }&lt;br /&gt;       myHandlers orElse super.trafficHandlers //Use our partials *first* before others&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice the boiler-plate code here.  We're chaining our partial functions in a way that makes this work like chain-of-command.  All partial functions from "myHandlers" should be checked before our super-class trafficHandlers.  However, to make this work, we end up with a not-quite-so-good-looking syntax.  This should just show itself when defining the class hierarchy, code that uses this pattern shouldn't really be able to tell how  we're implementing our chain of command pattern, e.g.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//Imagine setting up a complex simulation item that has various roles mixed in.&lt;br /&gt;val webServer = new ProxyWebServer with ModularWebServer {&lt;br /&gt;   addModule(new CgiModule());  //In our hypothetical simulation, this simulates the overhead of making CGI calls.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;val results = for( msg &lt;- simulateMessages) yield {&lt;br /&gt;  webServer !! msg &lt;br /&gt;}&lt;br /&gt;//TODO - Loop through results and analyze simulation&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see, this can lead to some nice functionality and composability of your actor-entities.&lt;br /&gt; The question remaining in my mind is "Can the boilerplate be reduced in scala".  Ideally I would love to be able to do the following (for this situation):&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;trait NetworkDaemon extends Actor {&lt;br /&gt;   partial def trafficHandlers(msg : Any) : Unit  //Abstract partial function&lt;br /&gt;   def act() {&lt;br /&gt;       loop(react(trafficHandlers))&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;trait WebServer extends NetworkDaemon {&lt;br /&gt;   //Implements the partial def with an implementation&lt;br /&gt;   partial def trafficHandlers(msg : Any) : Unit = {&lt;br /&gt;       case HttpRequestForStaticResource(resource) =&gt; reply(resource.getContents)&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;trait ServletWebServer extends WebServer {&lt;br /&gt;  //Completely overrides our parents partial function&lt;br /&gt;   override partial def trafficHandlers(msg : Any) : Unit = {&lt;br /&gt;      case ProxyableConnection(...) =&gt; forward(...)&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;trait ProxyWebServer extends WebServer {&lt;br /&gt;   //Adds our implementation before our parents&lt;br /&gt;   override partial def trafficHandlers(msg : Any) : Unit = {&lt;br /&gt;      case ProxyableConnection(...) =&gt; forward(...)&lt;br /&gt;      super //This means delegate to the partial function defined on our super class (could be qualified)&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;trait DevNullDaemon extends NetworkDaemon {&lt;br /&gt;   //Overrides the partial definition with a *complete* definition&lt;br /&gt;   //This could be useful for enforcing completeness at a given layer of the hierarchy.&lt;br /&gt;   override def trafficHandlers(msg : Any) : Unit = {&lt;br /&gt;         //ignore&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I'm still debating the syntax on delegating to a superclass partial function, but the general gist is to allow similar mechanisms to method over-riding/chaining but instead with partial functions, as well as the ability to define partial functions as methods on a class.  Currently, I only see this feature covering a niche of use cases, but it could be quite handy for those.  Behind the scenes, the compiler would be desugaring the syntax into something like the original implementation.  &lt;br /&gt;&lt;br /&gt;If anyone else is interested in seeing this kind of functionality in scala, perhaps we should get together and produce a SIP (after fixing up the "delegating to super" syntax...).  I've debated trying to accomplish this with a compiler plugin and annotations, and I still may go that route for a proof of concept.  (Granted, this all requires enough free time to actually finish one of my side projects!).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-7953146759790388602?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/7953146759790388602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=7953146759790388602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/7953146759790388602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/7953146759790388602'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/04/partial-functions-inheritance.html' title='Partial Functions + Inheritance'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-8364545904412650827</id><published>2009-03-28T08:53:00.002-04:00</published><updated>2009-03-28T09:03:05.542-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Tricksy JBoss AS</title><content type='html'>So, initially when I heard that JBoss AS 5.0 was going to modular, of course I thought "OSGi".  This has been the precedence for Glassfish and Spring DM.  However, the next set of news I had was from some OSGi advocates railing on JBoss for rolling their own module system.  However, I ran across this link that makes things more apparent &lt;a href="http://interopy.wordpress.com/2008/06/30/most-awaited-jboss-50-soon-to-come/"&gt;Most Awaited JBoss 5.0 Soon to come&lt;/A&gt;.&lt;br /&gt;&lt;br /&gt;If you read between the lines, it appears like JBoss went with their own module framework so that:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;they could find a way to appease the OSGi community (as they propose that their implementation is compatible)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;support legacy MBean components&lt;/li&gt;&lt;br /&gt;&lt;li&gt;inter operate between various implementations (conjecture: jigsaw?)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;It's my opinion that this was actually a wise move, assuming the effort was not very high.  This is because Project Jigsaw is still an unknown in the modularization market, and perhaps JBoss is positioning themselves to be one of the first to support it.&lt;br /&gt;&lt;br /&gt;As long as I can use some nice OSGi module-based solutions in the meantime, I think this is a big win for JBoss as an App server choice.  I'd prefer  however for modularization to make into Java via a JCP (and therefore into the JEE spec), so at least there's some kind of standard implementation that can be used (with servers like JBoss able to provide proprietary extensions if desired).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-8364545904412650827?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/8364545904412650827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=8364545904412650827' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8364545904412650827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8364545904412650827'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/03/tricksy-jboss-as.html' title='Tricksy JBoss AS'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-948191201600016454</id><published>2009-03-19T20:31:00.007-04:00</published><updated>2009-03-25T20:36:46.243-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><category scheme='http://www.blogger.com/atom/ns#' term='novajug'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Why you want to learn Scala!</title><content type='html'>Why you want to learn Scala!&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Below are the slides from &lt;a href="http://novajug.wordpress.com/2009/03/19/mar-24-why-you-want-to-learn-scala-by-josh-suereth/"&gt;the talk&lt;/a&gt; I gave to the Northern Virginia Java user's group.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src='http://docs.google.com/EmbedSlideshow?docid=dfqn4jb_11cxdvdmff&amp;amp;size=m' frameborder='0' width='555' height='451'&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;A few random errata from the meeting:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;A few minor introductions to Scala's type system/generics may be helpful&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I messed up my description of Nothing and Unit.  &lt;a href="http://www.scala-lang.org/docu/files/ScalaReference.pdf"&gt;Page 130 of the Scala Spec&lt;/a&gt; has a diagram of the type system.  Nothing + Null are at the "bottom" meaning they psuedo-inherit from every type.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I need to flesh out my examples a bit, especially pattern matching.  I'll try to update the slides as I find time&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Apache MINA + Scala - &lt;a href="http://blog.richdougherty.com/2007/11/mina-bindings-for-scala.html"&gt;blog posting&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://planetscala.com/"&gt;Planet Scala&lt;/a&gt; - A scala news aggregator.  I recommend checking out old posts from scala-blogs and graceless failures &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Update: Here's a picture of me giving the presentation.  &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zY6AYwdFmgA/ScrN5oLvD7I/AAAAAAAAACc/Rr-oPDbg6R4/s1600-h/CIMG3331.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_zY6AYwdFmgA/ScrN5oLvD7I/AAAAAAAAACc/Rr-oPDbg6R4/s320/CIMG3331.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5317288699987169202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thanks to all who attended! I thought interaction was really good, and was excited to see so much enthusiasm!&lt;br /&gt;&lt;br /&gt;-Josh&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-948191201600016454?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/948191201600016454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=948191201600016454' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/948191201600016454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/948191201600016454'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/03/why-you-want-to-learn-scala.html' title='Why you want to learn Scala!'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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://2.bp.blogspot.com/_zY6AYwdFmgA/ScrN5oLvD7I/AAAAAAAAACc/Rr-oPDbg6R4/s72-c/CIMG3331.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-795108538432563176</id><published>2009-03-06T08:51:00.002-05:00</published><updated>2009-03-06T09:06:04.739-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jee 6'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><title type='text'>Way to go Spring Source!</title><content type='html'>&amp;lt;rant&amp;gt;&lt;br /&gt;&lt;br /&gt;It's good to see some &lt;a href="http://jcp.org/en/jsr/results?id=4821"&gt;critical feedback&lt;/a&gt; on the JEE spec.  I'm glad I'm not the only one questioning some of the merits of the JSRs.  I'm also disappointed that the blog-o-sphere picked up on Apache's "the JCK is not really open" complaints, but seem to have completely missed (or don't have a response to) SpringSource's "too much, in the wrong places" complaint.&lt;br /&gt;&lt;br /&gt;Granted, Seam looks to be very interesting.  The biggest killer (IMHO) is JSF.  Now, if the new JSF spec fixes that... perhaps it could be viable.  The question remains, are Spring's complaints of "too much risk" valid? (Seam appears to be a pretty good working prototype of this JSR).  Yes it would be nice to have way to easily piece together  simple data driven web-apps.  I personally believe JEE is still overkill for this.  &lt;br /&gt;&lt;br /&gt;Regardless, I think it is most important that the entire Java stack makes it easy to "compose" software.  The easier it is to "compose" the more it encourages people to write modular code.  I don't think dependency injection =&gt; modular code, but it sure encouraged *some* folks to start writing better code. &lt;br /&gt;&lt;br /&gt;Although spring is a *rather large* codebase, it still feels to be one of the better designed library stacks for the Enterprise Development.  I often find classes inside it highly useful.  More so than the JEE spec.  Possibly it's because they took a closure-like approach to their apis.  Hmmm..... closures + java? what a novel idea.  &lt;br /&gt;&lt;br /&gt;&amp;lt;/rant&amp;gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-795108538432563176?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/795108538432563176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=795108538432563176' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/795108538432563176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/795108538432563176'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/03/way-to-go-spring-source.html' title='Way to go Spring Source!'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-308738821404958769</id><published>2009-02-14T09:35:00.018-05:00</published><updated>2009-02-15T15:52:26.536-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='traits'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>How should traits in Scala be used?</title><content type='html'>This blog is a survey of the way I've seen traits used in various scala projects (including my own).  The purpose of this article is to explore the new-found (at least to those coming from java) power of traits and determine what works well and what the cost/benefits are of each.  The taxonomy used in this Blog is non-standard.  I believe if I read more of the academic papers, I'd know the real names attributed to these usages, but for now I believe the names chosen will suffice to describe the concepts.  &lt;i&gt;(If anyone knows appropriate references to articles/papers please comment with links!)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Traits as Interfaces&lt;/b&gt;&lt;br /&gt;This is the most-natural usage of traits for Java developers.  This is where you define a trait that has no method definitions (only declarations).  The traits then act merely as interface definitions, and allow developers to code to the interface of a class, rather than any specific implementation of it.  I like to use these when defining entry points for third-party implementers to use when entering the "domain" of a given library.  It allows my library to interact with the users classes without having to know anything about their implementations.  I also like to use this for high-level constructs I pass out of my library, as it keeps the user of the library from knowing too much about the specifics of the implementation.&lt;br /&gt;&lt;br /&gt;An example of this comes from my earliy post about writing a Scala DSL for Database Migrations.  Here's the trait that was passed to all migration scripts in the DBMigrationEngine:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;trait MigrationContext {&lt;br /&gt;  &lt;br /&gt;  def createTable[A](name : String)(creatorScript : TableCreator =&gt; A) : A&lt;br /&gt;  def executeScript(queries : Function[DbVendor,String]) : Unit&lt;br /&gt;  &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I'm not sure what all to say about these, except that they provide nice clean interfaces between larger modules of your system.  They can also be compilation barriers (assuming they don't change frequently and you manually specify them in return types... I know sometimes I get lazy here with scala's nice type inference).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Traits as Abstract Classes&lt;/b&gt;&lt;br /&gt;This usage comes naturally to those of us coming at Scala from C++.  A trait can be treated as an abstract virtual class with all virtual methods.   This means we can proivde a very rich interface for a class, while only requiring subclasses to implement one or two "pure virtual" (or undefined) methods.  The Scala collections libraries have good examples of traits as Abstract classes.  Let's look at the Seq class in Scala.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Seq class in scala implements all sorts of nice collections functions, flatMap, map, foreach, isEmpty, etc.   However to create your own sequence, you only need to override the following methods:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  def length: Int&lt;br /&gt;  def elements: Iterator[A]&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This is perhaps the style of traits that I find myself developing most for my various projects.  It has all the familiarity of a Java abstract class, but all the power of real multiple-inheritance.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Traits as Bolt-Ons&lt;/b&gt;&lt;br /&gt;This is where trait self types really find their use.  The goal of a bolt-on trait is to add functionality (or "bolt on") to an existing class.  Bolt-on traits are very similar to decoraters in that they "decorate" existing classes with functionality.  As you can create mixin traits when instantiating objects, it has almost as much flexibility in construction as Decorators, only methods don't need to pass down to delegates.  Bolt-on traits serve more purposes than just decoration though (as the above example doesn't quite fit the decorator pattern).  &lt;br /&gt;&lt;br /&gt;In my own projects, I've created two very simple bolt-on traits that I think show case the idea.  These two traits are "InitializingSpringActorBean" and "DisposableSpringActorBean".  The basic of just of these traits are that they are to be mixed in *only* with Actor subclasses.  They implement the "InitialzingBean" and "DisposableBean" interfaces of Spring in the context of actors.  Here's the source code for the InitializingBean:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/** &lt;br /&gt; * This is a trait which will start an actor after a bean's properties have been set.&lt;br /&gt; */&lt;br /&gt;trait InitializingSpringActorBean extends InitializingBean { &lt;br /&gt;  self : Actor =&gt;  &lt;br /&gt;  override def afterPropertiesSet() {&lt;br /&gt;    start&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice the usage of the self type.  This ensures that the trait can only be mixed into an actor class, and (IMHO) is what makes it a "bolt-on" trait.   This particular trait implements an interface from spring that enables the Spring BeanContext (or IoC Container) to call "start" on an Actor at the correct point in the Spring lifecycle.  Typical usage of this would be:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/**&lt;br /&gt; * Some kind of bean the emulates business logic.&lt;br /&gt; */&lt;br /&gt;@Service("CoffeeBean")&lt;br /&gt;class CoffeeBean extends Actor with InitializingSpringActorBean {&lt;br /&gt;  ... Injected properties...&lt;br /&gt;  override def act() {&lt;br /&gt;        ...&lt;br /&gt;  }&lt;br /&gt;  //No need to call start as spring knows how/when to start us now!&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The thing to always remember about traits, is that when editing one that defines methods, you must recompile all the *subclasses* of the trait as well.  This is because the mangling Scala uses to implement traits duplicates the methods in each of its concrete subclasses.  So far, most of my bolt-on classes have been rather simple, and do not need to be constantly tweaked/recompiled, but this is a valid concern for a large project.  As in C++, I would reserve bolt-on traits for cross-cutting concerns or specific applications.  (The most commonly used "bolt-on" from my C++ days was boost::non_copyable, which luckily for me, hardly ever changed!  However the issues are the same in Scala as they were in C++ [assuming all code resides in header files])&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Traits as Class Ecosystems&lt;/b&gt;&lt;br /&gt;This is perhaps one of the neatest (and dangerous) usage of traits I've seen so far in Scala.  This is where a trait contains one or more definitions of classes that operate together.   These classes are all used to solve a particular problem. If trait includes some high level methods to call into it ecosystem, it really starts to resemble a facade pattern.  However, there are many other uses of this, such as the Virtual Class pattern (shown off in the eclipse plugin).  This use of traits (once again in my opinion) has the potential for pure awesome and the greatest potential for pure evil.  Here is actual Ecosystem trait code with the code removes to help protect the innocent (or guilty?)&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;trait Files {&lt;br /&gt;   class FileDependencies{&lt;br /&gt;        class Tracker extends OpenHashMap[File, Set[File]]{...}&lt;br /&gt;        ...&lt;br /&gt;   }&lt;br /&gt;   object FileDependencies {...}&lt;br /&gt;   case class File ... {...}&lt;br /&gt;}&lt;br /&gt;object Files extends Files&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You can see that the above ecosystem consists of a FileDependencies class, a FileDependencies Object and a File class.   The ecosystem trait also provides convenience methods for using the above classes (not shown above).  In the above example, the trait actually provides some implicit conversions for "files" form another ecosystem (namely the java standard library) to be automatically converted into this ecosystem.  Finally (and important to me) is there is a static Object provided from which one can gain access to the ecosystem *without* mixing in the trait (i.e. import Files._ works somewhat similarly to extends Files).  Ecosystem traits also take form in two interesting ways in the Scala Compiler and the Scala Eclipse Plugin.&lt;br /&gt;&lt;br /&gt;I'm going to hold off discussing the Scala compiler because it deserves its own blog entry.  The Scala Compiler uses what is known as the "Cake" pattern.   Martin Odersky (creator of Scala) outlines the Cake Pattern in his description of how the scala compiler was creating in his paper "Scalable Component Abstractions."   The paper is quite worth the read, and you should all google for it and read it RIGHT NOW.  However, the pattern isn't without critics.  I've heard it mentioned a few places as the "Bakery of Doom" used in the compiler.  Why do some developers love this pattern and others hate it?   Well, you'll have to wait for my next entry, as I'd like to really spend some time delving into this.  &lt;br /&gt;&lt;br /&gt;For now, let's look into an easier (and smaller) code base for trait ecosystem examples: The Scala Eclipse Plugin.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;The Eclipse Plugin and Virtual Class pattern.&lt;/b&gt;&lt;br /&gt;The Scala Eclipse Plugin makes heavy use of "Virtual Classes".   The original author of the plugin (Sean McDirmid) outlines a simple skeleton of the pattern/idiom used when creating Virtual classes in scala &lt;a href="http://lambda-the-ultimate.org/node/1960#comment-23826"&gt;here&lt;/a&gt;.  Virtual Classes originated (AFAIK) in the programming language BETA, and is described &lt;a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=7&amp;url=http%3A%2F%2Fwww.disi.unige.it%2Fetaps2001%2FPRESENTATIONS%2FMADSEN.ppt&amp;ei=fHiXSdKfJte4twfCj4ifCw&amp;usg=AFQjCNGYF4P_YrEAr1KIvdQ8xHCSJ5NPmg&amp;sig2=J4RDHX44Dgk_SSE2H6o8RA"&gt;here&lt;/a&gt;.   BETA is an interesting language (for those interested in languages), but the pattern itself holds interest to us in Scala, and is used a great deal in the Eclipse Plugin.&lt;br /&gt;&lt;br /&gt;The main benefit of the Virtual Class "pattern" is that you can layer not only your application, but your "types" or classes".   At the lower levels, the class only contains methods needed by lower levels, and as you move up the inheritance chain, the Class "fills out" with all the necessary method.  This helps create a minimal interface for the lower levels, while providing a robust interface for the higher levels.&lt;br /&gt;&lt;br /&gt;The virtual class pattern is great when you need to slowly build a type in a variety of layers, and slightly change behavior in each layer.   However, it does have some downsides.  One of which is that unit testing partial types isn't a walk in the park.  You actually need to create a "final" layer for the virtual class and unit test that.  You end up doing this for every layer in the pattern.  As creating a new layer means implementing the entire ecosystem, you're no longer really unit tests, as you are integration testing.   I believe as long as you *do* testing, it shouldn't affect the overall stability of your project.&lt;br /&gt;&lt;br /&gt;The real issues show up in terms of sprawl.  I believe an inherit weakness in using virtual classes is the desire to shrink your layers into minimal sets of functionality (a good thing) and then re-use layers in many many different places (perhaps not so good a thing).  The virtual class layers really need well-defined boundaries in the system and preferably low-level (or facade-like) entry points to keep them loosely coupled.  If you decide to create virtual-classes for things like lists and strings, it would be very hard to loosely couple this code.  (Reminds me of private inheritance from C++)  The eclipse plugin really showcases the issues involved in designing with virtual classes (as well as showcasing the benefits).  The plugin actually implemented a much faster (but not 100% correct) algorithm to improve recompilation speeds for itself.  This is because of the massive amount of trait-inheritance sprawl in the plugin.&lt;br /&gt;&lt;br /&gt;To illustrate my point, I've tried to make a few Ven diagrams of the "ecosystem traits" in the eclipse plugin.  The names of each "bubble" are real trait names.  I've left out showing the internal ecosystem classes, as the diagram gets very cluttered very quickly.  In terms of a Ven Diagram, you can assume that any trait (or bubble) encapsulating another bubble mean "inheritance", as inheritance of "ecosystem" traits involves merging the two, well, ecosystems of objects.   Here's the diagram just for the lampion.core package:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_zY6AYwdFmgA/SZdL9njA8PI/AAAAAAAAACM/OpxZeI2mNCw/s1600-h/lampion.core-package.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 143px;" src="http://4.bp.blogspot.com/_zY6AYwdFmgA/SZdL9njA8PI/AAAAAAAAACM/OpxZeI2mNCw/s320/lampion.core-package.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5302790608211996914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Notice how most of the ecosystem traits extend each other before reaching the RangeTrees trait.  This is a side effect of using the Virtual Class pattern.  Each trait partially defines a type with the outer ecosystem traits refining the ones from the inner ecosystem, as well as adding new types.   Things get slightly more confusing when we bring in one more scala eclipse plugin package (and this is the furthest I'll go for clarity).  &lt;br /&gt;&lt;br /&gt;The next diagram not only has the above ven diagram features, but I've also added thick black lines to denote "is-the-same-as" and dashed lines to denote package boundaries.   As scala promotes multiple inheritance this idea of one ecosystem encapsulating another gets interesting, as it's possible to merge the same ecosystem from different parent ecosystems.  You'll see interesting code spattered around the eclipse plugin to handle this.   Here's my representation of the lampion.core and lampion.compiler plugin:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_zY6AYwdFmgA/SZdNcf8e5KI/AAAAAAAAACU/5SvijlqtpcY/s1600-h/lampion.compiler-package.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 305px;" src="http://1.bp.blogspot.com/_zY6AYwdFmgA/SZdNcf8e5KI/AAAAAAAAACU/5SvijlqtpcY/s400/lampion.compiler-package.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5302792238258906274" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see besides a horrible color selection, things in the plugin are really getting interesting.  The Parsers trait inherits every ecosystem class from lampion.core (except for Plugin).  The consequences are any change to any class (even internal to an ecosystem) involve recompiling parsers (and therefore typers and tokenizers... not to mention their subclasses).  Once again, realize that the eclipse plugin defines its own dependency analysis to recompilation to attempt to bring its cost down to one that is acceptable for development.  This seems to me a like a "bad smell" to on of the pieces in the plugin, and I'm pointing at the over-use of virtual-classes (and traits in general) in the plugin.  &lt;br /&gt;&lt;br /&gt;My biggest complaint (as stated before) with the design (as it exists in the eclipse plugin) is there are no boundaries for the Virtual Class pattern.  As you can see, if I were to ven diagram the eclipse plugin, almost all classes would be encompassed be a few high-level classes, with minor amounts of utility code/standalone classes here and there.  Not only is the barrier to learning the pattern high (without appropriate documentation), the maintenance (and recompilation) costs are also high.  The virtual-class pattern is useful in the right contexts (and a portion of the eclipse plugin might even have that context), but it seems like more of a golden-hammer approach as it stands, and tends to dissuade me from using virtual classes in plugin enhancements/bug fixes that I try to contribute.&lt;br /&gt;&lt;br /&gt;I also believe one reason the eclipse plugin gets far more criticism than scalac (besides lack of design documentation) is the lack of automated testing.  Although unit testing (as mentioned above) is rather difficult, integration testing is not, and there should be a very strong integration test suite accompanying the plugin.  This would not only prove the virtual class pattern is viable for its current usage, it could also help new developers see how the layers work, and what is expected of each.  I would love to see a project that uses the virtual class pattern with a strong set of integration tests to prove my theory correct (that integration testing can make up for the pain of unit testing virtual classes).&lt;br /&gt;&lt;br /&gt;&lt;b&gt; Conclusions&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;If you have any examples of traits being used (either efficiently or horribly) please make some noise!  I'd love to get a better sampling to color the descriptions in this blog.&lt;br /&gt;&lt;br /&gt;To the Java developer, Scala provides new-found power, and requires a modified approach to design.  Coming from C++ to Scala, I've been able to apply quite a bit of knowledge on software architecture, however there are still some things that Functional Programming brings to the table that I need to wrap my head around.  I'd like to challenge those that have real-world experience in designing large-scale scala systems to start sharing some knowledge of helpful practices/tips and architectures.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-308738821404958769?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/308738821404958769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=308738821404958769' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/308738821404958769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/308738821404958769'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/02/how-should-traits-in-scala-be-used.html' title='How should traits in Scala be used?'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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/_zY6AYwdFmgA/SZdL9njA8PI/AAAAAAAAACM/OpxZeI2mNCw/s72-c/lampion.core-package.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-6555573507138374616</id><published>2009-02-05T19:41:00.012-05:00</published><updated>2009-02-05T22:32:47.075-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scalac plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><category scheme='http://www.blogger.com/atom/ns#' term='annotations'/><title type='text'>Levaraging Annotations in Scala Part 2: scalac Plugins</title><content type='html'>This post began as a discussion on #scala about how people define a public "getter" method and private "setter" method using only defs and vars in scala.  The usual method in scala is:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class MyClass {&lt;br /&gt;   private var x_private : Int = _&lt;br /&gt;   def x = x_private&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The downside to this is that you have two names to express one concept.  I'm at the point where I'm no longer caring too much about public/private parts of classes, but I thought I'd tackle the problem to exercise my new-found compiler skills.  It turns out this feat is pretty easy to accomplish via a scalac plugin.&lt;br /&gt;&lt;br /&gt;To create your first plugin you should follow the guide &lt;a href="http://www.scala-lang.org/node/140"&gt;here&lt;/a&gt;.  We'll be using the Maven as our build tool, since to do otherwise would be blasphemy (for me).&lt;br /&gt;&lt;br /&gt;To start off with, here's the POM file for our plugin:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&amp;gt;&lt;br /&gt; &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt; &amp;lt;groupId&amp;gt;org.scala-lang&amp;lt;/groupId&amp;gt;&lt;br /&gt; &amp;lt;artifactId&amp;gt;private-setter-scalac-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt; &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;&lt;br /&gt; &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt; &amp;lt;name&amp;gt;Var definition extensions for the scala compiler&amp;lt;/name&amp;gt;&lt;br /&gt; &amp;lt;url&amp;gt;http://suereth.blogspot.com&amp;lt;/url&amp;gt;&lt;br /&gt; &amp;lt;repositories&amp;gt;&lt;br /&gt;  &amp;lt;repository&amp;gt;&lt;br /&gt;   &amp;lt;id&amp;gt;scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;   &amp;lt;name&amp;gt;Scala-tools Maven2 Repository&amp;lt;/name&amp;gt;&lt;br /&gt;   &amp;lt;url&amp;gt;http://scala-tools.org/repo-releases&amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;/repository&amp;gt;&lt;br /&gt; &amp;lt;/repositories&amp;gt;&lt;br /&gt; &amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;  &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;   &amp;lt;id&amp;gt;scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;   &amp;lt;name&amp;gt;Scala-tools Maven2 Repository&amp;lt;/name&amp;gt;&lt;br /&gt;   &amp;lt;url&amp;gt;http://scala-tools.org/repo-releases&amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt; &amp;lt;/pluginRepositories&amp;gt;&lt;br /&gt; &amp;lt;dependencies&amp;gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.scala-lang&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;scala-compiler&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;2.7.3&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt;&lt;br /&gt; &amp;lt;/dependencies&amp;gt;&lt;br /&gt; &amp;lt;build&amp;gt;&lt;br /&gt;  &amp;lt;plugins&amp;gt;&lt;br /&gt;   &amp;lt;plugin&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;org.scala-tools&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;maven-scala-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;executions&amp;gt;&lt;br /&gt;     &amp;lt;execution&amp;gt;&lt;br /&gt;      &amp;lt;goals&amp;gt;&lt;br /&gt;       &amp;lt;goal&amp;gt;add-source&amp;lt;/goal&amp;gt;&lt;br /&gt;       &amp;lt;goal&amp;gt;compile&amp;lt;/goal&amp;gt;&lt;br /&gt;       &amp;lt;goal&amp;gt;testCompile&amp;lt;/goal&amp;gt;&lt;br /&gt;      &amp;lt;/goals&amp;gt;&lt;br /&gt;     &amp;lt;/execution&amp;gt;&lt;br /&gt;    &amp;lt;/executions&amp;gt;&lt;br /&gt;    &amp;lt;configuration&amp;gt;&lt;br /&gt;     &amp;lt;jvmArgs&amp;gt;&lt;br /&gt;      &amp;lt;jvmArg&amp;gt;-Xms64m&amp;lt;/jvmArg&amp;gt;&lt;br /&gt;      &amp;lt;jvmArg&amp;gt;-Xmx1024m&amp;lt;/jvmArg&amp;gt;&lt;br /&gt;     &amp;lt;/jvmArgs&amp;gt;&lt;br /&gt;    &amp;lt;/configuration&amp;gt;&lt;br /&gt;   &amp;lt;/plugin&amp;gt;&lt;br /&gt;   &amp;lt;plugin&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;shitty-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;executions&amp;gt;&lt;br /&gt;     &amp;lt;execution&amp;gt;&lt;br /&gt;      &amp;lt;goals&amp;gt;&lt;br /&gt;       &amp;lt;goal&amp;gt;clean&amp;lt;/goal&amp;gt;&lt;br /&gt;       &amp;lt;goal&amp;gt;install&amp;lt;/goal&amp;gt;&lt;br /&gt;       &amp;lt;goal&amp;gt;test&amp;lt;/goal&amp;gt;&lt;br /&gt;      &amp;lt;/goals&amp;gt;&lt;br /&gt;     &amp;lt;/execution&amp;gt;&lt;br /&gt;    &amp;lt;/executions&amp;gt;&lt;br /&gt;   &amp;lt;/plugin&amp;gt;&lt;br /&gt;  &amp;lt;/plugins&amp;gt;&lt;br /&gt; &amp;lt;/build&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's a few things in this pom, mostly to ensure that the scala-tools repositories are available too us.  Also, ignore the shitty (Super-Helpful-Integration-Testing-ThingY) plugin for now.  The most important part is that we're compiling to a jar file, and we're depending on the scala-compiler.   The version of the compiler we depend on is the *only* version of scala your plugin should be used with.  In all reality, the scala-compiler should probably be deifned as a 'provided' dependency and the scala-library should explicitly be depended on, but for now we'll cheat on completeness.&lt;br /&gt;&lt;br /&gt;Next we need to make sure there is a scalac-plugin.xml file in the created JAR. This is simple in maven, just place one in the src/main/resources directory.   Here is what my src/main/resources/scalac-plugin.xml looks like:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;  &amp;lt;name&amp;gt;private-setters&amp;lt;/name&amp;gt;&lt;br /&gt;  &amp;lt;classname&amp;gt;org.scala_lang.privateSetter.internal.privateSetterPlugin&amp;lt;/classname&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You'll notice I'm naming my plugin "private-setters" and placing it in a "internal" package.   This could be my eclipse plugin development rubbing off, but this helps me know what only the compiler should see.&lt;br /&gt;&lt;br /&gt;Next we need a way for clients of our plugin to "notify" us that they want a var with a private setter method (varname_=), but public getter (varname).   Here's my initial cut at client syntax:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;import org.scala_lang.privateSetter._&lt;br /&gt;class TestWidget {&lt;br /&gt;  @privateSetter&lt;br /&gt;  var myVar = 5  &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Pretty simple really, but effective.  (Also I already know how to look up annotations from my scala-mojo-support project, so it only took me a few hours to work out the scalac plugin details.   This post actually took the most amount of time in the whole venture).&lt;br /&gt;&lt;br /&gt;Now we need to define the privateSetter annotation we can use in our classes.  It's a fairly simple file:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;package org.scala_lang.privateSetter&lt;br /&gt;/** This annotation is used to make a var's setter method be private */&lt;br /&gt;class privateSetter extends StaticAnnotation {&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Next we need to write the plugin itself.  All plugins contain some boiler-plate code, so we'll ignore that for the time being. (see the &lt;a href="http://www.scala-lang.org/node/140"&gt;documentation mentioned above&lt;/a&gt;).  The truly interesting part of this plugin is the newly defined phase.&lt;br /&gt;&lt;br /&gt;For some history, the Scala Compiler (scalac) is composed of various "phases".  Each phase has a responsibility it performs.  Some phases are easy to identifier e.g. "icode" which converts the AST to icode for each "compilation unit".  In the Scala Compiler a compilation unit corresponds to a source code file and may produce multiple class files.  Here's the scalac -Xlist-phases output on my machine:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;br /&gt;$ scalac -Xshow-phases&lt;br /&gt;namer&lt;br /&gt;typer&lt;br /&gt;superaccessors&lt;br /&gt;pickler&lt;br /&gt;refchecks&lt;br /&gt;liftcode&lt;br /&gt;uncurry&lt;br /&gt;tailcalls&lt;br /&gt;explicitouter&lt;br /&gt;erasure&lt;br /&gt;lazyvals&lt;br /&gt;lambdalift&lt;br /&gt;constructors&lt;br /&gt;flatten&lt;br /&gt;mixin&lt;br /&gt;cleanup&lt;br /&gt;icode&lt;br /&gt;inliner&lt;br /&gt;closelim&lt;br /&gt;dce&lt;br /&gt;jvm&lt;br /&gt;sample-phase&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;On to our implementation!  The basic structure of our phase looks like this:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/** The actual phase the removes units from being compiled that are up-to-date */&lt;br /&gt;    class MakeSettersPrivatePhase(prev: Phase) extends Phase(prev) {&lt;br /&gt;      &lt;br /&gt;      override def name = VarAccessChanger.this.name&lt;br /&gt;      import global._&lt;br /&gt;      /**&lt;br /&gt;       * Called when our plugin is running.&lt;br /&gt;       */&lt;br /&gt;      override def run {&lt;br /&gt; for (unit &amp;lt;- global.currentRun.units; if !unit.isJava) {&lt;br /&gt;           unit.body = TreeTransformer.transform(unit.body)      &lt;br /&gt; }&lt;br /&gt;      }&lt;br /&gt;      ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I'll mention that this class is nested inside an outer "Plugin" class which is passed the 'global' object.  For those of you unfamiliar with the compiler, the "Global" object is the outer layer of the "cake" pattern used by the Scala Compiler.  I'm reserving judgment on Global, but I have noticed that it's very hard to unit test any "module" you write for Global (as most of them have the "self:Global =&amp;gt;" syntax).  &lt;br /&gt;&lt;br /&gt;The Transformer is a very nice class for doing AST manipulation (thanks DRM for suggesting it).   This class simply transforms the AST from one form to another.  It's perhaps the easiest way to implement our plugin.  Let's set up a Tree Transformation that does absolutely nothing useful:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/** &lt;br /&gt;       * This object transforms the AST of a compilation unit apply our PRIVATE metamorphosis for vars.&lt;br /&gt;       */&lt;br /&gt;      object TreeTransformer extends Transformer {&lt;br /&gt;        /**&lt;br /&gt;         * This method transforms individual nodes of the tree.&lt;br /&gt;         */&lt;br /&gt;        override def transform(tree: Tree) = tree match {&lt;br /&gt;         case t =&amp;gt;         &lt;br /&gt;           super.transform(t)&lt;br /&gt;       }&lt;br /&gt;      }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The structure here is we override the transform method.  This method takes a tree and returns a tree.  We want to transform *only* the setter part of a var method if it contains the privateSetter annotation.   Let's apply our pattern matching skills to the test with an extractor:  The "AnnotationSetterShouldBePrivate" extractor.&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/** &lt;br /&gt; * Selector to remove annotated var setters &lt;br /&gt; */&lt;br /&gt;object AnnotatedSetterShouldBePrivate {&lt;br /&gt;  /** &lt;br /&gt;   * Pattern matcher for privateSetter annotated setter methods &lt;br /&gt;   */&lt;br /&gt;  def unapply(node : Tree) : Option[DefDef] = {&lt;br /&gt;    /** &lt;br /&gt;     * Helper method to determine if a public setter method has the privateSetter annotation. &lt;br /&gt;     */&lt;br /&gt;    def hasPrivateSetterAnnotation(annotations : List[Annotation]) : Boolean = {&lt;br /&gt;      for {&lt;br /&gt;           annotation &amp;lt;- annotations&lt;br /&gt;           if annotation.tpe.safeToString == classOf[privateSetter].getName&lt;br /&gt;      } {&lt;br /&gt;        return true&lt;br /&gt;      }&lt;br /&gt;      false&lt;br /&gt;    }&lt;br /&gt;    node match {&lt;br /&gt;      case x @ DefDef(mods,name,_,_,_,_) if name.toString.endsWith("_$eq") =&amp;gt;&lt;br /&gt;         if(hasPrivateSetterAnnotation(mods.annotations)){&lt;br /&gt;            Some(x)&lt;br /&gt;         } else {&lt;br /&gt;            None&lt;br /&gt;         }&lt;br /&gt;      case _ =&amp;gt; None&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;First, note that our extractor (unapply method) takes in a tree and returns a DefDef.  DefDef is the AST class for a "def" node.   All var's are parsed into dual "def" methods (setter and getter).  We define a helper method that takes a list of annotations and looks for our "privateSetter" annotation.   The actually implementation of the extractor matches against the tree node, checks to see if it's a DefDef and has a tailing name of "_$eq".   "_$eq" is the mangled form of "_=" which is the convention for scala setter methods.  Note that I probably could move the if/else statement into the pattern match on the DefDef, but wasn't feeling adventurous enough this evening.  In the case where we find a valid annotated setter DefDef method, we return it, otherwise return None.&lt;br /&gt;&lt;br /&gt;Now that we have our extractor, writing the tree transformation becomes fairly simple:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/** &lt;br /&gt; * This object transforms the AST of a compilation unit apply our PRIVATE morphosis for vars.&lt;br /&gt; */&lt;br /&gt;object TreeTransformer extends Transformer {&lt;br /&gt;    &lt;br /&gt;  /**&lt;br /&gt;   * This method transforms individual nodes of the tree.&lt;br /&gt;   */&lt;br /&gt;  override def transform(tree: Tree) = tree match {&lt;br /&gt;      case AnnotatedSetterShouldBePrivate(d @ DefDef(mods,name,tparams,vparams,tpt,impl)) =&amp;gt; &lt;br /&gt;          import symtab.Flags._&lt;br /&gt;          val tree = copy.DefDef(d, mods | PRIVATE,name,tparams,vparams,tpt,transform(impl))&lt;br /&gt;          tree.symbol.setFlag(PRIVATE)              &lt;br /&gt;          tree&lt;br /&gt;      case t =&amp;gt;        &lt;br /&gt;          super.transform(t)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see, we're combining our "AnnotatedSetterShouldBePrivate" extractor with the natural extractor for the DefDef case class so that we can pull out all the constructor variables (along with the DefDef itself using the "d @" syntax).  Initially I tried returning just a newly constructed DefDef with "mods | PRIVATE" instead of "mods" in the constructor.  You'll find this blows up horribly.   The main issue is that the AST nodes contain *more* than just their constructor values (types and symbols being the two things I found).   The Transformer class provides a "copy" value/object that you can use to "copy" various parts of the tree.   The copy class contains a method for every tree node that takes an original tree and overriding constructor values.  For our purposes, we're applying the PRIVATE flag to the "mods" attribute of the DefDef and two the symbol flags for the DefDef.  The symbol flags are what are eventually used in the icode-&amp;gt;bytecode conversion code.&lt;br /&gt;&lt;br /&gt;Next we should choose what phase to run this plugin after.  I've chosen the "typer" phase, as this ensures we at least have an AST and the types are correct.  When defining a class in isolation, this is working perfectly.  However when defining the class and using it with other classes, I'm running into the difficulty where the methods I'm modifying are eventually being replaced with public methods of a differing names.  To look into this, we should set up some integration tests.  NOW we can use the SHITTY plugin!&lt;br /&gt;&lt;br /&gt;The maven shitty plugin allows you to execute "integration" projects that depend on the currently "building" project.   You simple create a directory in src/it, add a pom.xml that depends on your project (with a version of "testing"), and a goal.txt that describes which maven goals should be executed.   If the integration project's maven build succeeds, the overall project's maven build continues.  If an integration project's maven build fails, the entire build fails.  This works great for "positive" tests (or test where you make sure that things compile with your plugin).   Let's define a relatively simple positive test.   First, we take the class outlined earlier as our example syntax:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;package org.scala_lang.privateSetter&lt;br /&gt;/** This annotation is used to make a var's setter method be private */&lt;br /&gt;class privateSetter extends StaticAnnotation {&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next we create a pom file for this integration test:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&amp;gt;&lt;br /&gt; &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt; &amp;lt;groupId&amp;gt;org.scala-tools&amp;lt;/groupId&amp;gt;&lt;br /&gt; &amp;lt;artifactId&amp;gt;testPrivateSetter&amp;lt;/artifactId&amp;gt;&lt;br /&gt; &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;&lt;br /&gt; &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt; &amp;lt;name&amp;gt;test-privateSetter-scalac-plugin&amp;lt;/name&amp;gt;&lt;br /&gt; &amp;lt;dependencies&amp;gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;org.scala-lang&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;private-setter-scalac-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;testing&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt;&lt;br /&gt;  &amp;lt;dependency&amp;gt;&lt;br /&gt;   &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;&lt;br /&gt;   &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;&lt;br /&gt;   &amp;lt;version&amp;gt;4.5&amp;lt;/version&amp;gt;&lt;br /&gt;   &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;  &amp;lt;/dependency&amp;gt;&lt;br /&gt; &amp;lt;/dependencies&amp;gt;&lt;br /&gt; &amp;lt;build&amp;gt;&lt;br /&gt;  &amp;lt;plugins&amp;gt;&lt;br /&gt;   &amp;lt;plugin&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;org.scala-tools&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;maven-scala-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;executions&amp;gt;&lt;br /&gt;     &amp;lt;execution&amp;gt;&lt;br /&gt;      &amp;lt;goals&amp;gt;&lt;br /&gt;       &amp;lt;goal&amp;gt;add-source&amp;lt;/goal&amp;gt;&lt;br /&gt;       &amp;lt;goal&amp;gt;compile&amp;lt;/goal&amp;gt;&lt;br /&gt;      &amp;lt;/goals&amp;gt;&lt;br /&gt;     &amp;lt;/execution&amp;gt;&lt;br /&gt;    &amp;lt;/executions&amp;gt;&lt;br /&gt;    &amp;lt;configuration&amp;gt;&lt;br /&gt;     &amp;lt;compilerPlugins&amp;gt;&lt;br /&gt;      &amp;lt;dependency&amp;gt;&lt;br /&gt;       &amp;lt;groupId&amp;gt;org.scala-lang&amp;lt;/groupId&amp;gt;&lt;br /&gt;       &amp;lt;artifactId&amp;gt;private-setter-scalac-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;       &amp;lt;version&amp;gt;testing&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;/dependency&amp;gt;&lt;br /&gt;     &amp;lt;/compilerPlugins&amp;gt;&lt;br /&gt;     &amp;lt;args&amp;gt;&lt;br /&gt;      &amp;lt;arg&amp;gt;-verbose&amp;lt;/arg&amp;gt;&lt;br /&gt;     &amp;lt;/args&amp;gt;&lt;br /&gt;    &amp;lt;/configuration&amp;gt;&lt;br /&gt;   &amp;lt;/plugin&amp;gt;&lt;br /&gt;  &amp;lt;/plugins&amp;gt;&lt;br /&gt; &amp;lt;/build&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;repositories&amp;gt;&lt;br /&gt;  &amp;lt;repository&amp;gt;&lt;br /&gt;   &amp;lt;id&amp;gt;scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;   &amp;lt;name&amp;gt;Scala-tools Maven2 Repository&amp;lt;/name&amp;gt;&lt;br /&gt;   &amp;lt;url&amp;gt;http://scala-tools.org/repo-releases&amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;/repository&amp;gt;&lt;br /&gt; &amp;lt;/repositories&amp;gt;&lt;br /&gt; &amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;  &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;   &amp;lt;id&amp;gt;scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;   &amp;lt;name&amp;gt;Scala-tools Maven2 Repository&amp;lt;/name&amp;gt;&lt;br /&gt;   &amp;lt;url&amp;gt;http://scala-tools.org/repo-releases&amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;/pluginRepository&amp;gt; &lt;br /&gt;  &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;   &amp;lt;id&amp;gt;snapshots.scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;   &amp;lt;name&amp;gt;Scala-tools Maven2 Snapshot Repository&amp;lt;/name&amp;gt;&lt;br /&gt;   &amp;lt;url&amp;gt;http://scala-tools.org/repo-snapshots&amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt; &amp;lt;/pluginRepositories&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You'll notice we're making us of the "testing" version of our plugin AND the "compilerPlugin" configuration option of the maven-scala-plugin.   This option is new to the (not yet released except as a SNAPSHOT) 2.10 version, and allows you to depend on any number of scalac plugins during your build.  We're using it now to depend on our build.  Our goals.txt simply consists of "clean compile".  &lt;br /&gt;&lt;br /&gt;Another thing that the SHITTY plugin lets you do is provide a 'validate.groovy' file with your pom.xml and goals.txt.   This file is run after a build to ensure things were successful.   We can use this to ensure our generated classfiles have private setters.  We'll tackle that problem another day (I'm currently being lame and running javap on the .class files).&lt;br /&gt;&lt;br /&gt;I think I've typed as much as I can for one night, I'll try to cover the remaining pieces (after I code/finish them) later.  Once again, there are some issues with the plugin as I'm confusing the hell out of some of the compiler phases (not to mention being confused myself as to where things happen in some cases).  If you'd like to look at the source (and perhaps contribute? ), it's available on github: &lt;a href="http://github.com/jsuereth/private-setter-scalac-plugin/tree/master"&gt;private-setter-scalac-plugin&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6555573507138374616?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6555573507138374616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6555573507138374616' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6555573507138374616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6555573507138374616'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/02/levaraging-annotations-in-scala-part-2.html' title='Levaraging Annotations in Scala Part 2: scalac Plugins'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-8288344227526519467</id><published>2009-01-20T20:45:00.021-05:00</published><updated>2009-01-21T09:23:42.528-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='protocopter'/><category scheme='http://www.blogger.com/atom/ns#' term='lolcode'/><category scheme='http://www.blogger.com/atom/ns#' term='prototype oo'/><category scheme='http://www.blogger.com/atom/ns#' term='io language'/><title type='text'>The Protocopter Story</title><content type='html'>To steal the words of Chesterton...  This posting is about a yachtsman, who thinks he's discovered a new island off the south seas, only to realize he had discovered England.  The man lands (armed to the teeth) and plants the British flag in a barbaric temple which turns out to be the pavilion in Brighton.  As Chesterton states, I will reiterate "I am that man."&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Beginning&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The story begins over a year ago with Adam Lindsay's invention of &lt;a href="http://lolcode.com"&gt;LOLCode&lt;/a&gt;.  I was shown this language sometime in the summer of 2007, and decided I would try my hand at writing an Eclipse plugin for it.   The plugin turned into an interpreted runtime, which flowed to my more active involvement in the shaping of the language.  While the language itself is rather humorous and very readable, the most interesting part to me were the concepts we were describing.&lt;br /&gt;&lt;br /&gt;LOLCode is designed by committee, which although allows for many various interesting ideas to get discussed, also leads to very-long debates and slow decision making.  However, a few major pieces of LOLCode were decided early that shaped it into a very interesting language.  Of primary importance was the appeal to feline programmers.  This untapped market could revolutionize the software business for decades to come.  It was later agreed that other fuzzy and/or exceptionally cute lifeforms should also be allowed to participate in this revolution.  The most exciting decision (for me) was the decision to use Prototype-OO as the basis for the language. Most other design decisions fell from this.&lt;br /&gt;&lt;br /&gt;While designing LOLCode, not only were we having fun, we were also toying with some very interesting programming language designs.  The choice of prototype-OO lead to several other interesting choices, that eventually got a few of us excited about the possibilities what the language could express.  Not only could you perform acts for others, you may also be able to do so succinctly and elegantly.  This lead to the idea for "Protocopter"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;A Language that can fly&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/jsuereth/protocopter/tree/master"&gt;Protocopter&lt;/a&gt; is a language runtime (currently very buggy + implemented on top of Scala) that we were using to test out the ideas of LOLCode in a very minimal syntax.  The idea was to reduce parse complexity (as most of us weren't compiler designers by profession) while ironing out details in the runtime.  So far, we've had some very exciting results, and I'd like to go over the general design/implementation of Protocopter/LOLCode for you.  For future reference I will only use protocopter, but the designs are interchangeable at this point.  Protocopter is almost a "vm" for LOLCode.&lt;br /&gt;&lt;br /&gt;&lt;b&gt; SLOTS IN YR OBJECT &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The primary design of Protocopter revolves around its object construct.   An object is a "thing" that may contain any number of "slots".   Each slot has a name, and contains any number of objects.   The concept is very similar to Java's Map&amp;lt;String,Object&amp;gt; and almost exactly the same of a JavaScript object.&lt;br /&gt;&lt;br /&gt;The most interesting part about Protocopter objects are that they have prototypes.  A "prototype" is essentially a parent class only it remains an object.  In Ruby, you can access a class and inject methods into it, but in Protocopter there is no need.  Everything is an object.  IF you want to create a "class", you simple make an object (places all methods/fields you want inside) and then prototype it to create "instances".   The concept shouldn't be new for any AJAX developer, but it can be rather unintuitive for C/Java programmers.  &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zY6AYwdFmgA/SXanJ0MyBNI/AAAAAAAAAB8/vZNnoaqRml8/s1600-h/protocopter-slot-lookup.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 278px; height: 320px;" src="http://2.bp.blogspot.com/_zY6AYwdFmgA/SXanJ0MyBNI/AAAAAAAAAB8/vZNnoaqRml8/s320/protocopter-slot-lookup.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5293602199093511378" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The hard part in dealing with prototypes is defining how to look up a slot name on an object using its prototypes.  In Javascript, when looking for slot 'x', the object itself is initially queries for slot 'x'.  Then it proceeds to the prototype of the object, then the prototype of the prototype and so on.  In Protocopter we made the decision to allow a list of prototypes per object.   This means we needed a more sophisticated algorithm.   At the writing of this article, we've implemented a Depth-First search on the prototype list.  This means we first check the first prototype, then its first prototype, etc, until we've check as far down the tree as possible (the entire list), then recurse backwards searching for slot names.  The algorithm also marks objects that have been visited to prevent cyclic references from causing infinite lookup times.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now that we've defined objects, and slot lookups, what do prototypes really look like?  The prototype list needs to be modified at runtime, therefore it should fit in a slot.  Not only that, the prototype list is a LIST, ideally it should prototype the "ListPrototype" object, so we can re-use list functions when working with it.  All of these decision were made, although we haven't thoroughly defined the "ListPrototype" object, or how one would work with it.  &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Putting FUN back into FUNction &lt;/b&gt;&lt;br /&gt;Function are the next interesting piece to Protocopter.  There was much debate over how to create them, and what they should look like.  It was decided that the language should support blocks of code.   Blocks of code operate with some "scope object".  A scope object is the object used to look up local variables when a "block" is executing.  The block references these slots on the scope object without any qualifiers.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note: The initial script run by Protocopter is run in the scope of an anonymous prototype of the "Object" object.   Other potential prototypes may be implementation defined, but are non-standard.  "Object" is the only global inside Protocopter and the prototype of *every* object in the system.  &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;It was then decided to turn Functions into first-class objects.   A function consists of a code block and a list of arguments.  When calling a function, the function object is prototyped, and the arguments/self slots are assigned to the prototype.  The anonymous prototype is then used as the "scope object" for the code block of the function.  To turn a function into a closure, simply insert the "scope object" for the scope a function is created, into the function's prototype list.  Not only was this approach elegant, it made implementation much simpler (as it uses the already existing slot-lookup algorithm + prototype system).&lt;br /&gt;&lt;br /&gt;&lt;b&gt; WE HAZ A FLAVORZ &lt;/b&gt;&lt;br /&gt;The next part of protocopter was defining enough operations to make it a viable "VM" for lolcode.  The operations are listed below in the "Protocopter" syntax.  Later in the article I attempt list the relative LOLCode-&gt;Protocopter conversions.&lt;br /&gt;&lt;b&gt;Slot Access&lt;/b&gt;&lt;br /&gt;&lt;pre&gt; expr '.' identifier &lt;/pre&gt;  This access the value of a slot from an object&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Call Code Block/Function&lt;/b&gt;&lt;br /&gt;&lt;pre&gt; '!' expr expr expr*&lt;/pre&gt;  This calls a given code block with the scope/arguments&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Assign Slot&lt;/b&gt;&lt;br /&gt;&lt;pre&gt; l-value '&amp;lt;-' expr &lt;/pre&gt;  This assigns a value to a given slot&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create Prototype&lt;/b&gt;&lt;br /&gt;&lt;pre&gt; '~' expr &lt;/pre&gt;  This creates a prototype of an object&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Append Prototype&lt;/b&gt;&lt;br /&gt;&lt;pre&gt; l-value '&amp;lt;&amp;lt;' expr &lt;/pre&gt;  This appends a prototype to a given object&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Code Block&lt;/b&gt;&lt;br /&gt;&lt;pre&gt; '{' statement* '}' &lt;/pre&gt;  This creates a code block which will execute a series of statements.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Literal Translation &lt;/b&gt;&lt;br /&gt;&lt;pre&gt; '@' expr &lt;/pre&gt;  This treats a string expression as a code-literal (for slot lookup)&lt;br /&gt;&lt;br /&gt;The above form the basis for Protocopter syntax (and allow mapping from LOLCode).  I've also (somewhat successfully) tried to define a few convenience extensions in the current implementation.  These are not needed in the language, but helped me write some test cases quickly.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Function Definiton&lt;/b&gt;&lt;br /&gt;&lt;pre&gt; &lt;br /&gt;'{'  ('|' arg-list '|')?  statement* '}' &lt;br /&gt;arg-list := arg (',' arg)*&lt;/pre&gt;  &lt;br /&gt;This creates a Function object that takes a series of arguments.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Call-function inline syntax&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;expr '!' identifier call-arguments&lt;/pre&gt;  &lt;br /&gt;This syntax calls a function identified by a given slot on an object, using the object as "self" for the function.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Function Closure syntax&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;'[' ('|' arg-list '|')? statement* ']'&lt;/pre&gt;  &lt;br /&gt;This syntax creates a function that automatically prototypes the current scope.  &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Code-Block Closure syntax&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;'[' statement* ']'&lt;/pre&gt;  &lt;br /&gt;This syntax creates a code-block that automatically prototypes the current scope.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IM IN YR LOOP WHILE YR NOT!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now that we have some syntax available, it's easier to describe some issue's we're running into.  The first is how to deal with while loops.  Ideally, we want to implement tail-recursion optimizations and define while purely inside Protocopter like the function shown below (assuming 'if' is a valid function):&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;Object.while &lt;- { |condition, loop|  &lt;br /&gt;  ! if current (!condition) [ ! loop;  ! Object.while current condition loop ]&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Note that I'm using some lazy syntax here with the || arguments,  but let's look at the one-liner implementation.   First, you should note that code blocks return the last value executed in their scope.   Second you should note that "current" always refers to the current scope object.   I could accomplish this same code in more lines, but I'm preferring brevity here.  It might be more apparent what's going on if I write it without the syntax extensions.&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;Object.while &lt;- ~Function&lt;br /&gt;Object.while.block &lt;- {&lt;br /&gt;   trueBlock &lt;- { &lt;br /&gt;      !loop &lt;br /&gt;      ! Object.while current condition loop&lt;br /&gt;   }&lt;br /&gt;   trueBlock &lt;&lt; current&lt;br /&gt;   ! if current (!condition) trueBlock&lt;br /&gt;}&lt;br /&gt;list &lt;- ~ Object.libs.collection.List&lt;br /&gt;list.0 &lt;- 'condition'&lt;br /&gt;list.1 &lt;- 'loop'&lt;br /&gt;Object.while.args &lt;- list&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Notice first, that we're creating an anonymous prototype of "Function" and placing a code-block and argument list inside it. Then notice to create a closure, we're making a code-block and then appending the current scope as a prototype.  Also notice that we're using a very low-level mechanism of creating a list (assigning numbered slots).  Although it gets into the details, I hope that's detailing some of what is going on at the lower-levels of protocopter.  &lt;br /&gt;&lt;br /&gt;The goal with the protocopter language is to provide a very simple low-level base that LOLCode can be implemented on, while provided nicer higher-level language features that make writing boiler-plate test-code easier (like functions/closures, etc.).&lt;br /&gt;&lt;br /&gt;My next goal is to provide a few layers of niceties on top of the existing language extensions so you don't always have the verbose: "! function scope arg1 arg2" nonsense every time.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;CAN HAZ CHEEZBURGER?&lt;/b&gt;&lt;br /&gt;The most important part of Protocopter is the ability for LOLCode to compile into Protocopter instructions.  Currently they're both interpreted, so it's a mere matter of source-&gt;source translation, but hopefully in the future Protocopter could be a form of byte-code.&lt;br /&gt;&lt;br /&gt;Let's take a look at some LOLCode 1.3 spec examples and how they would look in Protocopter.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;I HAS A var ITZ 0 &lt;br /&gt;---------------------------------------&lt;br /&gt;var &lt;- 0&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;HOW DUZ I foo YR bar&lt;br /&gt; VISIBLE bar&lt;br /&gt;        FOUND YR NOOB&lt;br /&gt;IF U SAY SO&lt;br /&gt;---------------------------------------&lt;br /&gt;foo &lt;- { |bar|&lt;br /&gt;     ! print current bar&lt;br /&gt;     null &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;I HAS A thingy ITZ A Bukkit&lt;br /&gt;---------------------------------------&lt;br /&gt;thingy &lt;- ~ Bukkit&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;O HAI IM tired IM LIEK sleepy&lt;br /&gt;   I HAS A thingy ITZ 0&lt;br /&gt;KTHX&lt;br /&gt;---------------------------------------&lt;br /&gt;tired &lt;- ~sleepy&lt;br /&gt;! { thingy &lt;- 0 } tired&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;O HAI IM pile&lt;br /&gt;     I HAS A length IZ 0&lt;br /&gt;&lt;br /&gt;     HOW IZ I pushin YR item&lt;br /&gt;          ME HAS SRS length ITZ item&lt;br /&gt;          length R SUM OF length AN 1&lt;br /&gt;     IF U SAY SO&lt;br /&gt;&lt;br /&gt;     HOW IZ I popin&lt;br /&gt;          length R DIFF OF length AN 1&lt;br /&gt;          BTW Do bounds checking...&lt;br /&gt;          I HAS A mom ITZ ME'Z SRS length&lt;br /&gt;          ME'Z SRS length R NOOB&lt;br /&gt;          FOUND YR mom&lt;br /&gt;     IF U SAY SO&lt;br /&gt;KTHX&lt;br /&gt;---------------------------------------&lt;br /&gt;pile &lt;- ~Object&lt;br /&gt;! {&lt;br /&gt;   length &lt;- 0&lt;br /&gt;   pushin &lt;- { |item|&lt;br /&gt;      self.(@length) &lt;- item&lt;br /&gt;      self.length &lt;- ! + current self.length 1&lt;br /&gt;   }&lt;br /&gt;   poppin &lt;- { &lt;br /&gt;      self.length &lt;- ! - current self.length 1&lt;br /&gt;      mom &lt;- self.@length&lt;br /&gt;      self.@length &lt;- null&lt;br /&gt;      mom&lt;br /&gt;   }&lt;br /&gt;} pile&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;I HAS A fishBarrel ITZ A pile&lt;br /&gt;fishBarrel IZ pushin YR "halibut" MKAY&lt;br /&gt;fishBarrel IZ pushin YR "trout" MKAY&lt;br /&gt;fishBarrel IZ pushin YR "salmon" MKAY&lt;br /&gt;VISIBLE fishBarrel IZ popin MKAY  BTW prints "salmon"&lt;br /&gt;---------------------------------------&lt;br /&gt;fishBarrel &lt;- ~ pile&lt;br /&gt;! fishBarrel.pushin current "halibut"&lt;br /&gt;! fishBarrel.pushin current "trout"&lt;br /&gt;! fishBarrel.pushin current "salmon"&lt;br /&gt;! visible (! fishBarrel.popin current )&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;NOOOO HEZ STEALIN MAH BUKKIT!&lt;/b&gt;&lt;br /&gt;We've almost discovered England, and dug our flag into Brighton.  The only thing left is to look into a language known as &lt;a href="http://www.iolanguage.com/"&gt;IO&lt;/a&gt;.  I discovered this language a few weeks ago and it made me very excited and also very sad.  Not only is it almost exactly what we've been trying to implement with Protocopter, it even ups the ante with actor-based objects.   In I/O all objects are actors and all slot-access/function calls are messages between actors.  Most of the other work is already in-place in I/O.  While this gives me the satisfaction of knowing we were on the right track, it also begs the question:  What should we do with Protocopter?&lt;br /&gt;&lt;br /&gt;Currently the I/O language is a little too far removed for LOLCode to compile into its world.  However, would it be easier to finish Protocopter implementation, or re-define LOLCode 1.3 spec to fit the I/O language design?  I leave the debate up to the readers and the LOLCode forums.&lt;br /&gt;&lt;br /&gt;The unfortunately reality is that most of us trying to hack on Protocopter and LOLCode have more-than-full-time jobs and kids.  I also try to place the needs of the scala-maven-community before some of my other nerdy hobbies (which are way below family/work), so Protocopter ends up being pretty low on the totem pole.  Perhaps given enough insight, caffeine and hilarity to leverage, you'll see a 0.10 release of Protocopter (and 1.3 of LOLCode) out soon.&lt;br /&gt;&lt;br /&gt;Anyone willing to help, please email me and we'll set you up with access to the project and whatever else you need.   This blog now stand as the greatest single document of accumlated LOLCode-thought for the 1.3 spec.  If you'd like to see the thought process that arrived at this point, please check out the LOLCode forums.&lt;br /&gt;&lt;br /&gt;The current major issues in Protocopter are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sequence/List Prototype Definiton&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Using Sequences for Prototype lists on objects, and runtime manipulation&lt;/li&gt;&lt;br /&gt;&lt;li&gt;self/this references in functions.  How can we pass "scope" + "self" without being incredibly verbose&lt;/li&gt;&lt;br /&gt;&lt;li&gt;actor/continuation implementation + cleanup&lt;/li&gt;&lt;br /&gt;&lt;li&gt;parser refinement&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Code-Block slot/metadata definitions&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-8288344227526519467?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/8288344227526519467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=8288344227526519467' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8288344227526519467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8288344227526519467'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/01/protocopter-story.html' title='The Protocopter Story'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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://2.bp.blogspot.com/_zY6AYwdFmgA/SXanJ0MyBNI/AAAAAAAAAB8/vZNnoaqRml8/s72-c/protocopter-slot-lookup.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-6418438734364043667</id><published>2009-01-12T20:06:00.010-05:00</published><updated>2009-01-16T09:02:20.032-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mojo'/><category scheme='http://www.blogger.com/atom/ns#' term='scalac'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><category scheme='http://www.blogger.com/atom/ns#' term='annotations'/><title type='text'>Leveraging Annotations in Scala</title><content type='html'>This post attempts to explain how to leverage Scala annotations in the Scala language.  &lt;br /&gt;&lt;br /&gt;I'm currently working on the ability to create Maven 2 plugins (Mojos) in the Scala language.  Maven plugins are pretty easy to create, they basically involve creating a class that extends AbstractMojo and annotating fields on that class that should be injected with configuration/runtime information from maven.   Bringing this feature to Scala however, required me to make some trade-offs.  Should I use the "annotations in the documentation" approach that maven uses for java + groovy mojos?  Or should I leverage Scala's annotation support (which means I don't have to write a parser)?  I chose the annotation method, and below is how to make it work.&lt;br /&gt;&lt;br /&gt;First, we need a few annotations to leverage.  In the case of Maven Mojos, they're almost all defined for me.  Here's a look at the "goal" annotation:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class goal(val name : String) extends StaticAnnotation&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Scala defines two types of annotations (both extending from Annotation): Static and Classfile.  Classfile annotations are retained in the .class file (i.e. the byte code) and are available at runtime (I believe?).  Static annotations, on the other hand are 'available to the compiler'.  I haven't read through the SLS (Scala Language Spec), so I'm not quite sure exactly what this means, but I know they're at least available in the Abstract Syntax tree (what we care about).&lt;br /&gt;&lt;br /&gt;Those of you who use Java annotations will notice that Scala annotations do not provide as many options as Java annotations.  I'm hoping this changes with time, but currently Scala takes the standpoint that Java does a well enough job of defining annotations and annotation processing tools.  While I agree, I'd still like to be able to define annotations in Scala with a few more options.   However, defining annotations in Scala is more elegant than with Java (That's right Mr. @interface....)&lt;br /&gt;&lt;br /&gt;Next, let's make our first Maven mojo (something like the following):&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;@goal("echo")&lt;br /&gt;class EchoMojo extends AbstractMojo {&lt;br /&gt; &lt;br /&gt;  @throws(classOf[MojoExecutionException])&lt;br /&gt;  override def execute() {&lt;br /&gt;    getLog.error("HAI WURLDZ!")&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Next, we need to parse this file and create a "mojo description" xml file.  Maven provides us with an interface that is used to look for mojo-annotated classes.  We'll assume in your case (if you're leveraging annotations) that you already have hooks for where you will parse, and what you need to parse out.   To actually perform the parsing, we're going to steal a trick from scaladoc + the eclipse plugin called a "presentation-only" compiler.&lt;br /&gt;&lt;br /&gt;A "presentation-only" compiler is fairly easy to construct, you simply subclass the Scala "global" object and override its "onlyPresentation" method (as shown below).  The "Global" class is the amalgamation of all the various modules of the Scala compiler, plus a few methods to execute compilation.  &lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;val compiler = new Global(settings, reporter) {&lt;br /&gt;    override def onlyPresentation = true&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The Global class takes a settings object and a reporter.   The settings object contains all of Scalac's command-line settings in code form.  This is where you'll have to set the classpath and other fun flags (luckily for me, I get those for free from my maven mojo extractor interface).  The Reporter is simply a "strategy" for where to pipe error/compilation output to.  Once again, my choice is simple: The maven logger.&lt;br /&gt;&lt;br /&gt;After creating a compiler, you actually need to execute it against a list of source files (hopefully the ones containing your annotations) like so:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;val run = new compiler.Run&lt;br /&gt;run.compile(sourceFiles.toList) &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The "run" of the compiler should parse through all the files and generate an Abstract syntax tree for you.  After which, you can easily go rip through them all and process them, like so:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;for(unit &lt;- run.units if !unit.isJava) {&lt;br /&gt;  extractMojos(unit)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I'm purposefully ignoring Java files, as they're only parsed for mixed java-scala projects, and the maven Mojo extractor for Java already exists.&lt;br /&gt;&lt;br /&gt;Now for the real fun...  What does extractMojos look like?  Well, it has the following signature (give or take a few revisions in git):&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;def extractMojos(unit : compiler.CompilationUnit) : Unit&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;A CompilationUnit is a .scala or .java file that has been compiled.  A .scala file may contain many packages and classes/traits/objects.  We gain access to these by calling "unit.body".  The body is the Abstract Syntax tree for the given file.&lt;br /&gt;&lt;br /&gt;A little more context is needed for what we're going to do next.  The Scala Compiler uses something called the Cake pattern.  The gist of it is that you carve up functionality into modules (in this case traits) and mix them together as needed.  One unfortunate problem with the Scala Compiler itself is that a lot of the modules have nested dependencies (i.e. trait XYZ { self : Global =&gt; } ), and therefore have to be mixed into a global.   Therefore we're going to define our tree extraction methods on a trait (in a similar manner) and mix them into the compiler variable when we instantiate.  The module will look something like this:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;import scala.tools.nsc.ast._&lt;br /&gt;import scala.tools.nsc.symtab.{Flags, SymbolTable}&lt;br /&gt;import org.scala_tools.maven.mojo.annotations._&lt;br /&gt;trait MojoAnnotationExtractor {&lt;br /&gt;  self: Global =&gt;&lt;br /&gt;    &lt;br /&gt;  /** Pulls all mojo classes out of the body of source code. */&lt;br /&gt;  def parseCompilationUnitBody(body : Tree) : List[MojoParsedInfo] = {&lt;br /&gt;       //TODO - Implement&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;What " self : Global =&gt; " portion of code means, is that the trait &lt;b&gt;*must*&lt;/b&gt; be mixed into the Global class.  Assuming the above layer (trait) is fully implemented, the entire "annotation extraction compiler" looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  val compiler = new Global(settings, reporter) with MojoAnnotationExtractor {&lt;br /&gt;    override def onlyPresentation = true&lt;br /&gt;  }&lt;br /&gt;  val run = new compiler.Run&lt;br /&gt;  run.compile(sourceFiles.toList)       &lt;br /&gt;&lt;br /&gt;  //Extract mojo description&lt;br /&gt;  def extractMojos(unit : compiler.CompilationUnit) = {&lt;br /&gt;     import compiler._&lt;br /&gt;     for(info &lt;- compiler.parseCompilationUnitBody(unit.body)) yield {&lt;br /&gt;       extractMojoDescriptor(info)&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;  def extractMojoDescriptor(info : MojoParsedInfo) : MojoDescriptor = error("TODO - Implement")&lt;br /&gt;import scala.tools.nsc.ast._&lt;br /&gt;import scala.tools.nsc.symtab.{Flags, SymbolTable}&lt;br /&gt;import org.scala_tools.maven.mojo.annotations._&lt;br /&gt;trait MojoAnnotationExtractor extends CompilationUnits {&lt;br /&gt;  self: Global =&gt;&lt;br /&gt;    &lt;br /&gt;  /** Pulls all mojo classes out of the body of source code. */&lt;br /&gt;  def parseCompilationUnitBody(body : Tree) = {&lt;br /&gt;  for(unit &lt;- run.units if !unit.isJava) yield {&lt;br /&gt;    extractMojos(unit)&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I've added a few things in there.  First is the "with MojoAnnotationExtractor" as part of the Global class initialization.  This is mixing our our new extraction function (parseCompilationUnitBody), and allows us to call it inside the extractMojos method.  We're finally able to get to the meat of our application, actually pulling in annotations and doing something with them.&lt;br /&gt;&lt;br /&gt;The first thing we notice when attempting to parse the AST of a compilation unit body, is that we *must* keep track of package nesting ourselves... (there's no figuring it out after the fact, at least not cheaply that I found).  I ended up with the following helper to ensure I knew the package for each class:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt; /** Pulls all mojo classes out of the body of source code. */&lt;br /&gt;  def parseCompilationUnitBody(body : Tree) = {&lt;br /&gt;&lt;br /&gt;    //List of all the info about mojos we've found&lt;br /&gt;    var mojoInfos : List[MojoClassInfo] = List()&lt;br /&gt;&lt;br /&gt;    /** Parses down into packages... */&lt;br /&gt;    def parsePackage(pkgName : String, pkgDef : PackageDef) {&lt;br /&gt;&lt;br /&gt;      pkgDef.stats foreach { _ match {&lt;br /&gt;          //We found a package, recurse into it, keeping track of where we are&lt;br /&gt;          case subPkgDef : PackageDef =&gt;&lt;br /&gt;            parsePackage(pkgName + pkgDef.name + ".", subPkgDef)&lt;br /&gt;&lt;br /&gt;          //Find mojo classes&lt;br /&gt;          case classDef : ClassDef =&gt; parseMojoClass("", classDef)&lt;br /&gt;          case _ =&gt; //Ignore&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    //Pull top-level body if it's a package, or a class definiton.&lt;br /&gt;    body match {&lt;br /&gt;      case pkg : PackageDef =&gt; parsePackage("", pkg)&lt;br /&gt;      case classDef : ClassDef =&gt; parseMojoClass("", classDef)&lt;br /&gt;      case _ =&gt; Console.println("Error! Unexpected source file format for Scala Mojo Extractor");&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    mojoInfos&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The parsePackage code above is used to recurse into package tree nodes, and pull out any classes defined on them.  Scala converts the following code:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;package x.y.z;&lt;br /&gt;class A {}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; into the following Tree:  &lt;pre&gt;Package X &lt;- Package Y &lt;- Package Z &lt;- Class A&lt;/pre&gt;.&lt;br /&gt;This is because the above code is syntactically equivalent to&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;package x {&lt;br /&gt;  package y {&lt;br /&gt;     package z {&lt;br /&gt;         class A {}&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now that we at least have a method of finding classes, let's start looking into annotations.  We want to filter the classes we inspect based on whether they are executable Maven Mojos.  All maven mojos need to define a "goal" with which to run, corresponding to our "goal" annotation.  Let's throw this check before out parseMojoClass method:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;for { &lt;br /&gt;  annotation &lt;- classDef.mods.annotations&lt;br /&gt;  if annotation.tpe.safeToString == classOf[goal].getName&lt;br /&gt;} {&lt;br /&gt;  mojoInfos = parseMojoClass(pkgName + pkgDef.name + ".", classDef) :: mojoInfos&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The "ClassDef" node contains a "mods" branch which (among other things) holds A list of the annotations defined on a class.  Every annotation has a Type "tpe" field.  The "type" corresponds to the class of the annotation.  In this case I'm being lazy and calling the 'safeToString' method on type which should give me the full class name of that type (in this case org.scala_tools.mojo.annotations.goal).  I'm then comparing that to the runtime string of the class name, to ensure that the class does have a "goal" annotation.  &lt;i&gt;Note:  This was the path of least resistance for me.  Types are not guaranteed to be class names, so I'm  hoping to figure out a better way of doing this in the future.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The Scala syntax tree is very nice for doing manipulations and compilation like things, but for my circumstances, I really just want a map of annotation to attribute lists for that annotation.  Let's try to make an abstract method that will pull an annotation's name and all the "arguments" to it's constructor (i.e. @annotation(arg)).  I wound up with something like this:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt; &lt;br /&gt;  /** Parses a list of annotations into a list of MojoAnnotationInfo classes */&lt;br /&gt;  def parseAnnotations(annotations : List[Annotation]) = {&lt;br /&gt;      for {&lt;br /&gt;        annotation &lt;- annotations &lt;br /&gt;        Annotation(constr, _) &lt;- annotation&lt;br /&gt;      } yield {&lt;br /&gt;        // TODO - In the future the second arg to Annotation may be needed... (as it's what's inside the&lt;br /&gt;        //anonymous instantiation of an annotation, i.e. @xyz {}&lt;br /&gt;        //TODO - Do we need to match on constructor?&lt;br /&gt;        val argVals = for { &lt;br /&gt;          Apply(_, args) &lt;- constr&lt;br /&gt;          arg &lt;- args&lt;br /&gt;          argVal &lt;- extractStaticValue(arg)&lt;br /&gt;        } yield argVal&lt;br /&gt;        new MojoAnnotationInfo(annotation.tpe.safeToString, argVals.toList)&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  /** Attempts to pull a static value from the given tree.&lt;br /&gt;   * &lt;br /&gt;   * @returns&lt;br /&gt;   *         Some(value) if a value is found, None otherwise&lt;br /&gt;   */&lt;br /&gt;  def extractStaticValue(tree : Tree) = tree match {&lt;br /&gt;    case Literal(c) =&gt; Some(extractConstantValue(c)) &lt;br /&gt;    case _ =&gt; None&lt;br /&gt;  }&lt;br /&gt; /**&lt;br /&gt;   * Extracts a constant variable's runtime value&lt;br /&gt;   */&lt;br /&gt;  def extractConstantValue(c : Constant) = {&lt;br /&gt;    //TODO - handle other values&lt;br /&gt;    c.stringValue&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The for loop defined in 'parseAnnotations' is looking at every annotation and pattern matching to rip out their constructor (constr member).  If you need to support @annotation { val bodyVal = "someval" }, then you would also need to match against the second member of the "Annotation" AST node.&lt;br /&gt;&lt;br /&gt;The annotation constructor is an instance of the "Apply" AST node (which I believe means 'function call', but don't quote me).  Since I'm unconcerned over which "this" is being called, we are only extracting the 'args' field from the Apply node.  We then iterate through the list of argument AST nodes, and pass them to our "extractStaticValue" function.  Given that all annotation arugments must be statically accessible values, and that we implement extractStaticValue correctly, this should work just fine.&lt;br /&gt;&lt;br /&gt;Next the 'extractStaticValue' method is pulling "Literal" AST nodes and extracting their values.  A Literal AST can only hold a constant, so it pairs well with the 'extractConstantValue' method.  As you can see, I'm getting away with murder because non of my mojo annotations take anything but Strings.  In the "real world" you would need to handle static references as well constant values.&lt;br /&gt;&lt;br /&gt;The 'extractConstantValue' method takes an AST constant and pulls its string value.  The Constant AST class also has methods for pulling various other types of constants, however I'll leave a real implementation of 'extractConstantValue' as an excercise to the reader.  Once again, I only care about string constants.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The next processing I'd like to perform is to determine if there are any 'vars' in the MojoClass that I can inject maven resources into.  We'll assume we've defined a no-argument annotation called 'parameter' that you can place on var's like so:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  @parameter&lt;br /&gt;  @expression("${project.build.directory}")&lt;br /&gt;  var outputDirectory : File = _;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The above should inject the Maven Project's build output directory into the variable "outputDirectory" at runtime.   To do this, we need not only the name of the variable, but also it's type.  let's weed through the class AST's "impl" node and look for var definitions that have a @parameter annotation.&lt;br /&gt;&lt;br /&gt;You'll quickly notice that THERE IS NO VAR AST NODE!!!  Scala's very slick in that it converts the syntax:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  var xyz = _;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Into&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  def xyz = _&lt;br /&gt;  def xyz_= = _;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Therefore we need to look for the "Def" AST Nodes.  Not only that, we need to look for "setters" (i.e. methods ending with the string "_$eq", where $eq is the mangled form of = in a method name)&lt;br /&gt;&lt;br /&gt;Using the above code to parse through all annotations in a list, our "parameter" parser method looks like the following:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt; /** Pulls out information about all injectable variables based on mojo annotaitons. */&lt;br /&gt;    def parseMojoInjectedVars(classImpl : Tree) = {&lt;br /&gt;      for { node @ DefDef(mods,name,tparams,vparams,tpt,_) &lt;- classImpl&lt;br /&gt;            if name.toString.endsWith("_$eq")&lt;br /&gt;            annotation &lt;- mods.annotations&lt;br /&gt;            if annotation.tpe.safeToString == classOf[parameter].getName&lt;br /&gt;            argument @ ValDef(_,_,tpt,_) :: Nil &lt;- vparams //setter should only have ONE argument!&lt;br /&gt;      } yield {&lt;br /&gt;        val argName = name.toString.slice(0, name.length - "_$eq".length)&lt;br /&gt;        //DO a real extraction of the type!&lt;br /&gt;        val argType = tpt.toString&lt;br /&gt;        val argAnnotations = parseAnnotations(mods.annotations)&lt;br /&gt;        new MojoInjectedVarInfo(argName,argType,argAnnotations)&lt;br /&gt;      }&lt;br /&gt;    }    &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice the DefDef (Def AST Node) is made up of modifiers (annotations + others), a name (e.g. outputDirectory_$eq), type parameters, v? (regular) parameters, a return type and a body.  We use the name to filter out only var setter methods, and then look through the annotations for the parameter name.  Finally we filter out only methods that have ONE regular parameter, and we extract the type of that parameter with the pattern match "ValDef(_,_,tpt,_)".   We can then parse the annotations, and create our "Mojo Info" class.&lt;br /&gt;&lt;br /&gt;One thing I should mention is that all types I've been parsing so far have been in *external* libraries, and are therefore referencing class files in a jar somewhere.  I'll try to update the post as I get more robust in what my annotation processor can handle.&lt;br /&gt;&lt;br /&gt;Viola, we've extracted all the info for the beginnings of a scala mojo annotation processor.  The really fun part is generating a test case for it.   The test case involves running a maven integration test, where a new Scala Mojo project defines a mojo in scala, and the above code is used to generate the scala definition.  This integration-test project then has its *own* integration test where it creates another project and calls itself, verifying that it echoed "HAI" correctly to the output.&lt;br /&gt;&lt;br /&gt;Anyway, I hope this post was not too long for most of you.  The topic is fairly complex, and I'm not the best to be writing about it, however I hope that the few minutes it takes to read can save you the several hours of frustration I had trying to get things to work initially.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6418438734364043667?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6418438734364043667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6418438734364043667' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6418438734364043667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6418438734364043667'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/01/levaraging-annotations-in-scala.html' title='Leveraging Annotations in Scala'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-387712346887103607</id><published>2009-01-03T07:44:00.005-05:00</published><updated>2009-01-03T12:44:34.725-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fx script'/><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Initial thoughts on JavaFX</title><content type='html'>So recently I've been reading a little bit about the new "JavaFX" platform Sun has released.  Specifically I've been looking into the Fx Script language.  When I first heard about it, I kept thinking "OH no, *another* JVM language.  I hope they don't make it too similar to java!".   However, I've been pleasantly surprised by the features so far.&lt;br /&gt;&lt;br /&gt;Based on a few tutorials, JavaFX script appears to have chosen nice features from languages like Scala and Javascript, while adding one languages feature that truly distinguishes it (and IMHO makes it a worthwhile language to learn/use for its domain).  Here's a list of features I saw in the tutorials that I believe make the core of the Fx Script language:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Declarative Constructors (like javascript) - &lt;pre&gt;{ fieldName: value }&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Truly Useful Type inferences (with types on the right) [like scala] - &lt;pre&gt;var radius = 5.0&lt;/pre&gt;&lt;i&gt;Note: types can be specified&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Three main types of constructs (similar to scala) - mutable references, immutable reference and functions&lt;pre&gt;var mutableValue = 5.0&lt;br /&gt;def someStaticValue = 2.0&lt;br /&gt;function doSomething() {}&lt;br /&gt;&lt;/pre&gt;  These made me think scala's def=&gt; Fx's function, Scala's var=&gt; Fx's var and Scala's val=&gt; Fx's def&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Value Binding - (this is a truly compelling feature for JavaFX)&lt;pre&gt;var x = 0;&lt;br /&gt;def y = bind x;&lt;br /&gt;&lt;/pre&gt; The above code means that x and y will always have the same value, even though y is immutable.  This is useful for synching your model to your view.  I'm excited to start toying with this.  I've only shown on possible syntax, there are actually a few ways to bind variables. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Bound functions - &lt;pre&gt;var x = 0;&lt;br /&gt;def foo = bound function(...) {...};&lt;br /&gt;&lt;/pre&gt; The above code means that the function foo will see any changes made to "x".  I.e. foo is no longer a closure in the sense that it retains the value of x during its call.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Anyway, I'm pleasantly surprised with JavaFX and the Fx Script language.  I think a few good ideas from other JVM languages are finally really starting to take hold.   Most importantly, I'm glad Scala isn't the only viable JVM language with really useful type-inference.   I'm hoping the other statically typed languages will follow suit (This means you java!).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-387712346887103607?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/387712346887103607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=387712346887103607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/387712346887103607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/387712346887103607'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2009/01/initial-thoughts-on-javafx.html' title='Initial thoughts on JavaFX'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-5443890565512870313</id><published>2008-12-17T21:13:00.000-05:00</published><updated>2008-12-17T21:14:11.366-05:00</updated><title type='text'>Cora May Suereth</title><content type='html'>&lt;p class="mobile-photo"&gt;&lt;a href="http://2.bp.blogspot.com/_zY6AYwdFmgA/SUmx82ILFTI/AAAAAAAAAB0/jU6rmu8ElTs/s1600-h/photo-751367.jpg"&gt;&lt;img src="http://2.bp.blogspot.com/_zY6AYwdFmgA/SUmx82ILFTI/AAAAAAAAAB0/jU6rmu8ElTs/s320/photo-751367.jpg"  border="0" alt="" id="BLOGGER_PHOTO_ID_5280947696948679986" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-5443890565512870313?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/5443890565512870313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=5443890565512870313' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5443890565512870313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5443890565512870313'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/12/cora-may-suereth.html' title='Cora May Suereth'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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://2.bp.blogspot.com/_zY6AYwdFmgA/SUmx82ILFTI/AAAAAAAAAB0/jU6rmu8ElTs/s72-c/photo-751367.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-4869921531017314218</id><published>2008-12-12T19:42:00.006-05:00</published><updated>2008-12-12T20:29:31.909-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='extjs'/><title type='text'>Subclassing in ExtJS</title><content type='html'>It's been a while since I posted about ExtJS, so I thought I'd take a crack at another post here.  This is going to cover the &lt;pre&gt;Ext.extend&lt;/pre&gt; method, and how you go about sub-classing an Ext component.&lt;br /&gt;&lt;br /&gt;The basic just is that we are going to create a "constructor" method for the widget and bind it to a location (e.g. Ext.ux.data.MyDataStore).  Then we're going to use Ext.extend to plug in the methods of the parent objects, and override some at the same time.&lt;br /&gt;&lt;br /&gt;For our example, I'll be using the Ext.data.DataProxy class as what we're extending.&lt;br /&gt;&lt;br /&gt;So... first, let's define our constructor in a location:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//Ensures there are at least dummy objects leading into Ext.ux.data&lt;br /&gt;Ext.namespace('Ext.ux.data');&lt;br /&gt;&lt;br /&gt;Ext.ux.data.MyProxy = function(config){&lt;br /&gt;&lt;br /&gt;    Ext.ux.data.MyProxy.superclass.constructor.call(this);&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The code doesn't do a whole lot, but we have our constructor.  However when executing new Ext.ux.data.MyProxy() we get an error, superclass is *not* defined.  So... where does superclass come from?  It will actually be injected into our prototype via the Ext.extend method.   In fact, Ext.extend will also inject the methods "override" and "extend" into our class.  Here's our new class with the Ext.extend call:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//Ensures there are at least dummy objects leading into Ext.ux.data&lt;br /&gt;Ext.namespace('Ext.ux.data');&lt;br /&gt;&lt;br /&gt;Ext.ux.data.MyProxy = function(config){&lt;br /&gt;&lt;br /&gt;    Ext.ux.data.MyProxy.superclass.constructor.call(this);&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Ext.extend(Ext.ux.data.MyProxy, Ext.data.DataProxy);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now we can make use of DataProxy methods from within MyProxy using "this.methodName(args)".   This isn't very exciting yet because DataProxy is mostly an empty class (besides configuring the Observable class for us).&lt;br /&gt;&lt;br /&gt;The convention for adding methods into a subclass is to use the override parameter from Ext.extend.   This parameter is essentially an anonymous class containing methods to inject "over-top" of the parent class.  In the case where the method did not exist before, it is merely inserted.  Let's implement the load method (required for DataProxy subclasses) using this approach:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//Ensures there are at least dummy objects leading into Ext.ux.data&lt;br /&gt;Ext.namespace('Ext.ux.data');&lt;br /&gt;&lt;br /&gt;Ext.ux.data.MyProxy = function(config){&lt;br /&gt;    //Calls our super-class (Ext.data.DataProxy) constructor for full initialization&lt;br /&gt;    Ext.ux.data.MyProxy.superclass.constructor.call(this);&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Ext.extend(Ext.ux.data.MyProxy, Ext.data.DataProxy, {&lt;br /&gt;&lt;br /&gt;   //Load function as defined in HttpProxy, and needed for the "DataProxy interface..."&lt;br /&gt;   load: function(params, reader, callback, scope, callbackArg) {&lt;br /&gt;         params = params || {}; //Ensure params exists as an object&lt;br /&gt;         var result;&lt;br /&gt;         try {&lt;br /&gt;            //Use record reading to read "stock" data&lt;br /&gt;            result = reader.readRecords({ zombieKid: ['i', 'like', 'turtles'] });&lt;br /&gt;         } catch(e) {&lt;br /&gt;           //We had an issue pulling in stock data, fire appropriate events&lt;br /&gt;           //use callback in fail mode and bail.  This function is actually coming from&lt;br /&gt;           // the Observable class which is our "grandparent" class&lt;br /&gt;            this.fireEvent("loadexception", this, callbackArg, null, e);&lt;br /&gt;&lt;br /&gt;            callback.call(scope, null, callbackArg, false);&lt;br /&gt;&lt;br /&gt;            return;&lt;br /&gt;         }&lt;br /&gt;         //Inform the callback of the result of parsing our "stock" data&lt;br /&gt;         callback.call(scope, result, callbackArg, false);         &lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see... our load method is basically taking the reader (Record reader) passed in and attempting to read some stock data (calling appropriate callbacks as necessary).&lt;br /&gt;&lt;br /&gt;Notice the use of the "this.fireEvent" inside our method.  Because of how JavaScript handles resolution, this will refer to our fully constructed class at the time of invocation ( as opposed to definition), therefore the fireEvent method from Observable will be accessable from our object.&lt;br /&gt;&lt;br /&gt;The next important thing in defining your own widget is adding information to take in during construction.  Our superclass constructor does not take any arguments, hence the "Ext.ux.data.MyProxy.superclass.constructor.call(this);" in our constructor.  If perhaps our superclass constructor took a config object, we would have to change it.   Luckily our current widget constructor expects a config object, so we can just pass it through to our super (assuming the configs are complementary).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;Ext.ux.data.MyProxy = function(config){&lt;br /&gt;    //Calls our super-class (Ext.data.DataProxy) constructor for full initialization&lt;br /&gt;    Ext.ux.data.MyProxy.superclass.constructor.call(this, config);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Since the DataProxy class doesn't take anything in its constructor, we'll remove this, but it's an important feature to make note of.  Also remember you can make subclasses which could add/change configuration information sent to parents.  That's the nice part about having control of the config obejct before passing it to the superclass constructor.&lt;br /&gt;&lt;br /&gt;Now onto taking in our own information.  Let's mimic the "MemoryProxy" and take in some data during construction that we using during our "load" method.  We'll call this element 'data' in the config and our object.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;//Ensures there are at least dummy objects leading into Ext.ux.data&lt;br /&gt;Ext.namespace('Ext.ux.data');&lt;br /&gt;&lt;br /&gt;Ext.ux.data.MyProxy = function(config){   &lt;br /&gt;    //Pull out our "data"&lt;br /&gt;    this.data = config.data&lt;br /&gt;&lt;br /&gt;    //Calls our super-class (Ext.data.DataProxy) constructor for full initialization&lt;br /&gt;    Ext.ux.data.MyProxy.superclass.constructor.call(this);&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Ext.extend(Ext.ux.data.MyProxy, Ext.data.DataProxy, {&lt;br /&gt;&lt;br /&gt;   //Load function as defined in HttpProxy, and needed for the "DataProxy interface..."&lt;br /&gt;   load: function(params, reader, callback, scope, callbackArg) {&lt;br /&gt;         params = params || {}; //Ensure params exists as an object&lt;br /&gt;         var result;&lt;br /&gt;         try {&lt;br /&gt;            //Use record reading to read "passed in" data&lt;br /&gt;            result = reader.readRecords(this.data);&lt;br /&gt;         } catch(e) {&lt;br /&gt;           //We had an issue pulling in stock data, fire appropriate events&lt;br /&gt;           //use callback in fail mode and bail.  This function is actually coming from&lt;br /&gt;           // the Observable class which is our "grandparent" class&lt;br /&gt;            this.fireEvent("loadexception", this, callbackArg, null, e);&lt;br /&gt;&lt;br /&gt;            callback.call(scope, null, callbackArg, false);&lt;br /&gt;&lt;br /&gt;            return;&lt;br /&gt;         }&lt;br /&gt;         //Inform the callback of the result of parsing our "stock" data&lt;br /&gt;         callback.call(scope, result, callbackArg, false);         &lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The above is an almost exact duplicate of MemoryProxy.js from the ExtJS source.  I thought about having a more clever tutorial about a custom widget, but I'm trying to avoid assuming too much knowledge of ExtJS internals.  Anyway, I hope this makes you feel more comfortable creating your own classes and extending ExtJS widgets with custom functionality.   As always, let me know if you find any errors or typos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-4869921531017314218?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/4869921531017314218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=4869921531017314218' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/4869921531017314218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/4869921531017314218'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/12/subclassing-in-extjs.html' title='Subclassing in ExtJS'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-1697327258725593370</id><published>2008-12-02T17:16:00.004-05:00</published><updated>2008-12-02T17:32:36.497-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='repl'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='interpreter'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Debugging inside the Scala Eclipse Interpreter</title><content type='html'>So today we didn't have a babysitter, so I took the day to spend time with my daughter.  It was quite fun, and I actually had a chance to get to some of the scala development work I've been meaning to during her nap.&lt;br /&gt;&lt;br /&gt;Specifically, there have been a bunch of bugs with the Scala Eclipse plugin that really fall under contributions I've submitted.  Primarily relating to the Interpreter.&lt;br /&gt;&lt;br /&gt;After spending quite a long time getting my SDT development workspace working again (seriously... I have no idea why it's so hard to make it work on windows, but it is), I was up and running.  In about 20 minutes I managed to convert the original "roll-my-own jvm executor" to use Eclipse JDT's "Launch Configuration" support for a JVM.  Not only does this let people specify nice things like JVM arguments, it also rolls in the ability to actively debug.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's a screenshot of a workspace working off my locally installed scala plugin:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_zY6AYwdFmgA/STW08nXdH6I/AAAAAAAAABs/cZk8_VCkfq0/s1600-h/real-debug%2Binterpret.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 186px;" src="http://3.bp.blogspot.com/_zY6AYwdFmgA/STW08nXdH6I/AAAAAAAAABs/cZk8_VCkfq0/s320/real-debug%2Binterpret.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5275321491986915234" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hopefully this will make it into the trunk in a few weeks, depending on how much free time I can find.  There's still a few things I need to work out such as:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt; Wiring the old menu-style invocation to work with the new LaunchConfiguration&lt;/li&gt;&lt;br /&gt;  &lt;li&gt; Fixing/Tweaking the Launch Configuration Dialog to get rid of wonky behavior and allow configuration of things that matter&lt;/li&gt;&lt;br /&gt;  &lt;li&gt; Allow "bootstrap" code to send to the interpreter &lt;/li&gt;&lt;br /&gt;  &lt;li&gt; Ensure jline works correctly and eclipse passes down "interesting" keystrokes, OR roll my own &lt;/li&gt;&lt;br /&gt;  &lt;li&gt; Figure out how to wire into the syntax highlighter for a console &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;As you can see... it's already an extensive list.  I figure I'll at least get the basics done for the next release (2.8 I guess?)&lt;br /&gt;&lt;br /&gt;Anyway, if anyone wants to try out the code locally, let me know and I'll send you a .patch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-1697327258725593370?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/1697327258725593370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=1697327258725593370' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1697327258725593370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1697327258725593370'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/12/debugging-inside-scala-eclipse.html' title='Debugging inside the Scala Eclipse Interpreter'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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://3.bp.blogspot.com/_zY6AYwdFmgA/STW08nXdH6I/AAAAAAAAABs/cZk8_VCkfq0/s72-c/real-debug%2Binterpret.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-8620756372000763658</id><published>2008-11-16T09:21:00.017-05:00</published><updated>2009-10-09T22:21:18.741-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pattern matching'/><category scheme='http://www.blogger.com/atom/ns#' term='partial functions'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Using Partial Functions and Pattern Matching</title><content type='html'>As I dig further into scala, I begin to see the utility of certain language features when designing a library API.  &lt;br /&gt;&lt;br /&gt;For example, partial functions are a language feature in which you can declare functions that may or may not be defined for a given input.  A partial function (in scala) inherits from Function1 (one-argument function) and adds two interesting methods:&lt;br /&gt;   &lt;ul&gt;&lt;li&gt;&lt;b&gt;isDefinedAt&lt;/b&gt; - Check to see if the function "is defined" for a given input&lt;/li&gt;&lt;br /&gt;   &lt;li&gt;&lt;b&gt;orElse&lt;/b&gt; - Apply another partial function if this one is "undefined" for a given input&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;As you can see (by the orElse method), partial functions can make a chain-of-command pattern easy to implement using only language-level features.  The &lt;a href="http://www.liftweb.net/index.php/Main_Page"&gt;Lift web framework&lt;/a&gt; puts this to great use with their &lt;a href="http://www.liftweb.net/index.php/UrlRewriting"&gt;URL rewriting&lt;/a&gt; API.&lt;br /&gt;&lt;br /&gt;So how does one define a partial function?  It's as easy as defining a function made purely of case statements.  Here's a function that is only defined for a particular string:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&gt; val myPartial : PartialFunction[String,String] = {&lt;br /&gt;     |     case "mymatchedstring" =&gt; "my output string"&lt;br /&gt;     | }&lt;br /&gt;myPartial: PartialFunction[String,String] = &lt;function&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice how I only define one case that does *not* cover all potential strings.  Here's some examples of using "isDefinedAt" to check if a partial function can apply:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&gt; myPartial.isDefinedAt("mymatchedstring")&lt;br /&gt;res1: Boolean = true&lt;br /&gt;&lt;br /&gt;scala&gt; myPartial.isDefinedAt("someotherstring")&lt;br /&gt;res2: Boolean = false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What happens if you attempt to call a partial function on a string for which it is not defined?  &lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&gt; myPartial("mymatchedstring2")&lt;br /&gt;scala.MatchError: mymatchedstring2&lt;br /&gt; at $anonfun$1.apply(&lt;console&gt;:4)&lt;br /&gt; at $anonfun$1.apply(&lt;console&gt;:4)&lt;br /&gt; at .&lt;init&gt;(&lt;console&gt;:6)&lt;br /&gt; at .&lt;clinit&gt;(&lt;console&gt;)&lt;br /&gt; at RequestResult$.&lt;init&gt;(&lt;console&gt;:3)&lt;br /&gt; at RequestResult$.&lt;clinit&gt;(&lt;console&gt;)&lt;br /&gt; at RequestResult$result(&lt;console&gt;)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMe...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is a "MatchError" runtime exception.  I'd recommend using the isDefinedAt function and avoiding a runtime exception, but the choice is yours.&lt;br /&gt;&lt;br /&gt;Let's try adding the string "mymatchedstring2" to this partial function using orElse:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&gt; val partial2 : PartialFunction[String,String] = {&lt;br /&gt;     |   case "mymatchedstring2" =&gt; "Delegation FTW"      &lt;br /&gt;     | }&lt;br /&gt;partial2: PartialFunction[String,String] = &lt;function&gt;&lt;br /&gt;&lt;br /&gt;scala&gt; val doublePartial = myPartial orElse partial2&lt;br /&gt;doublePartial: PartialFunction[String,String] = &lt;function&gt;&lt;br /&gt;&lt;br /&gt;scala&gt; doublePartial.isDefinedAt("mymatchedstring")&lt;br /&gt;res5: Boolean = true&lt;br /&gt;&lt;br /&gt;scala&gt; doublePartial.isDefinedAt("mymatchedstring2")&lt;br /&gt;res6: Boolean = true&lt;br /&gt;&lt;br /&gt;scala&gt; doublePartial.isDefinedAt("mymatchedstring3")&lt;br /&gt;res7: Boolean = false&lt;br /&gt;&lt;br /&gt;scala&gt; doublePartial("mymatchedstring")             &lt;br /&gt;res8: String = my output string&lt;br /&gt;&lt;br /&gt;scala&gt; doublePartial("mymatchedstring2")&lt;br /&gt;res9: String = Delegation FTW&lt;br /&gt;&lt;br /&gt;scala&gt; doublePartial("mymatchedstring3")&lt;br /&gt;scala.MatchError: mymatchedstring3&lt;br /&gt; at $anonfun$1.apply(&lt;console&gt;:4)&lt;br /&gt; at $anonfun$1.apply(&lt;console&gt;:4)&lt;br /&gt; at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:38)&lt;br /&gt; at .&lt;init&gt;(&lt;console&gt;:8)&lt;br /&gt; at .&lt;clinit&gt;(&lt;console&gt;)&lt;br /&gt; at RequestResult$.&lt;init&gt;(&lt;console&gt;:3)&lt;br /&gt; at RequestResult$.&lt;clinit&gt;(&lt;console&gt;)&lt;br /&gt; at RequestResult$result(&lt;console&gt;)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ...&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Neato, now we can very easily create a chain-of-command pattern without defining any new classes (at least *I* don't define any new classes, the compiler may do whatever it needs to do).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let's try to make use of PartialFunctions for the &lt;a href="http://suereth.blogspot.com/2008/09/using-scala-for-domain-specific.html"&gt;Database Migration API&lt;/a&gt; I posted about several blog postings back.  The goal here is going to be creating a method of executing raw SQL queries during a migration.  We're aiming for something close to the following syntax:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;class Migration1 extends Migration {&lt;br /&gt; import MigrationDSL._&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; def upgrade(implicit ctx : MigrationContext) {&lt;br /&gt;  &lt;br /&gt;   execute_script {&lt;br /&gt;       case "MySQL" =&gt; """do mysql query;"""&lt;br /&gt;       case "Derby" =&gt; """Do derby query;"""&lt;br /&gt;   }  &lt;br /&gt;&lt;br /&gt; }&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The signature for the above execute will look something like the following:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;trait MigrationContext {  &lt;br /&gt;  def executeScript(queries : PartialFunction[String,String]) : Unit&lt;br /&gt;  ...  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object MigrationDSL {&lt;br /&gt;  def execute_script(queries : PartialFunction[String,String])(implicit ctx : MigrationContext) = ctx.executeScript(queries)&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Things are working pretty well so far.  We can try to detect the case when a migration is not defined for a given database vendor, and throw some sort of exception which will make the migration fail.  What if we'd like to give feedback to the user on whether or not they've left any supported databases "out" of their function?&lt;br /&gt;&lt;br /&gt;The preferred way to do that is via sealed traits,shown below:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;sealed trait DbVendor {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case class MySQL() extends DbVendor;&lt;br /&gt;&lt;br /&gt;case class Derby() extends DbVendor;&lt;br /&gt;&lt;br /&gt;case class Oracle() extends DbVendor;&lt;br /&gt;&lt;br /&gt;trait MigrationContext {  &lt;br /&gt;  def executeScript(queries : PartialFunction[DbVendor,String]) : Unit&lt;br /&gt;  ...  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object MigrationDSL {&lt;br /&gt;  def execute_script(queries : PartialFunction[DbVendor,String])(implicit ctx : MigrationContext) = ctx.executeScript(queries)&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now with the following code...&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;execute_script {&lt;br /&gt;       case MySQL() =&gt; """do mysql query;"""&lt;br /&gt;       case Derby() =&gt; """Do derby query;"""&lt;br /&gt;   }  &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... you don't see the desired error message.  Why?  Because we're taking a 'partial' function, which by definition could be undefined in certain locations.   To fix this we need to instead take a plain old vanilla function like below:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;&lt;br /&gt;trait MigrationContext {  &lt;br /&gt;  def executeScript(queries : Function[DbVendor,String]) : Unit&lt;br /&gt;  ...  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object MigrationDSL {&lt;br /&gt;  def execute_script(queries : Function[DbVendor,String])(implicit ctx : MigrationContext) = ctx.executeScript(queries)&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This informs the scala compiler that we expect the function to work for *all* inputs.  If we give the compiler a little encouragement (i.e. sealed classes/traits), it can now help us avoid "missing" possibilities in our case statements.&lt;br /&gt;&lt;br /&gt;Now with the following code...&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;execute_script {&lt;br /&gt;       case MySQL() =&gt; """do mysql query;"""&lt;br /&gt;       case Derby() =&gt; """Do derby query;"""&lt;br /&gt;   }  &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;.. will generate this error...&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre&gt;&lt;br /&gt;[WARNING] /home/josh/projects/blog/scala-db-migrate/src/main/java/com/blogspot/suereth/dbmigrate/test/Migration1.scala:16: warning: match is not exhaustive!&lt;br /&gt;[WARNING] missing combination         Oracle&lt;br /&gt;[WARNING] &lt;br /&gt;[WARNING]     execute_script({&lt;br /&gt;[WARNING]                    ^&lt;br /&gt;[WARNING] one warning found&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now our users can tell if they are handling every defined database vendor.  If they wish to ignore the message (or define a "generic" query to try to use, they can simply match on "_" (or wildcard) like so:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;execute_script {&lt;br /&gt;       case MySQL() =&gt; """do mysql query;"""&lt;br /&gt;       case Derby() =&gt; """Do derby query;"""&lt;br /&gt;       case _ =&gt; """Do generic query;"""&lt;br /&gt;   }  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we're no longer explicitly using partial functions, but our API can still make use of pattern matching.&lt;br /&gt;In a future post I plan to discuss how we can use extractors to do slick things with defining queries for specific versions of database vendors (or just all versions).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-8620756372000763658?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/8620756372000763658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=8620756372000763658' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8620756372000763658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8620756372000763658'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/11/using-partial-functions-and-pattern.html' title='Using Partial Functions and Pattern Matching'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-2449857706733384647</id><published>2008-10-31T15:38:00.009-04:00</published><updated>2008-10-31T16:40:35.079-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='new user'/><category scheme='http://www.blogger.com/atom/ns#' term='guide'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Maven For Beginners</title><content type='html'>&lt;span style="font-style:italic;"&gt;Not this content is also being submitted to the scala-lang.org site.  It is duplicated here mostly for peer review and for those of my readers who are *not* scala-centric.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This article is a more in-depth look at what maven is and how a new user can make use of it.  If you'd like a getting-started-quickly guide, please check out: &lt;a href="http://scala-blogs.org/2008/01/maven-for-scala.html"&gt;maven for scala&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;What is Maven?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Maven is modern build/project management tool.  According to its &lt;a href="http://maven.apache.org/what-is-maven.html"&gt;website&lt;/a&gt;, the core purposes are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Make the build process easy&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Provide a uniform build system&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Provide quality project information&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Provide guidelines for "best practices" in development&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Allows transparent migration to new features&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;In practice, maven can greatly simplify builds for "standard" projects, and makes it easier to add new libraries/modules to existing projects.  Maven builds tend to consist mostly of "declarations" and configuration, with very little scripting.  Maven also promotes the "convention over configuration" idea to reduce the length of build files.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Downloading Maven&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The first thing you need to get started with maven, is maven itself.  It can be downloaded from &lt;a href="http://maven.apache.org/download.html"&gt;http://maven.apache.org/download.html&lt;/a&gt;.  Unzip/untar it into a directory of your choice and make sure ${MAVEN_HOME}/bin is in your PATH (even on windows).  For some operating systems their are maven-packages you can download using your package manager.  There are also IDE integrations for most Java IDEs.  Some of these integration come with a version of maven "bundled" with the plugin (e.g. Eclipse IAM + Eclipse M2E).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Creating your first project&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After downloading maven, you should create a simple project to ensure that everything is working correctly.  This easiest way to do this is by using the Maven Archetype Plugin.  In maven an "archetype" is the general skeleton structure (or template) of a project.  You can run the archetype plugin as follows:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre&gt;mvn archetype:generate&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You may notice that maven has started downloading jar files onto your computer at this point.  Maven uses a dependency resolution mechanism that will download dependencies as needed (and only once).  If you're using a fresh install of maven, it may need to resolve the archetype plugin.&lt;br /&gt;&lt;br /&gt;Maven should give you a list of available project templates (scala was #30 on my list).  Select one that may interest you most (and if it's not scala... well....).&lt;br /&gt;&lt;br /&gt;Next maven will begin asking you for a groupId, artifactId, versionId and packaging.  We'll cover these later, but for now just use an inverted domain name for groupId (e.g. org.scala-lang) a project name for artifactId (e.g. test-project) and the default for veresionId/package.  Next cd test-project and run mvn package.  Once again you should see maven automatically downloading dependencies (such as scala-library, scala-compiler, junit, etc.)  Congratulations, you've built your first maven project!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Build File Structure&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Maven projects are defined by their "Project Object Model" or pom.  This file is located in the base directory of a maven project and is called pom.xml.   The Project Object Model includes a lot of different information:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The name/description of the project&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The style/packaging of the project&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The version of the project&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The dependencies (libraries or otherwise) of the project&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The configuration for the build (plugins, directories, etc.)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The configuration for reports (test coverage, static analysis, etc)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The developers/contributors for the project (name, email, etc.)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The Infrastructure (Source Control Repository, Continuous Integration Server, Issue Tracker) for the project&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The maven repositories used for the project&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;As you can see, this is a lot of information!  In addition to all this, POM files are object-oriented and may inherit from one parent.  By default, all maven projects inherit from the maven "master pom".  The master pom defines the standard build layout/configuration for maven projects.  You can override/extend this behavior in your project pom if desired.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;POM File&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's a standard maven pom file for a scala project:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&amp;gt;&lt;br /&gt;    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;org.scala-lang.demo&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;scala-test&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;name&amp;gt;Demo of maven for Scala Lang website&amp;lt;/name&amp;gt;&lt;br /&gt;    &amp;lt;url&amp;gt;http://scala-lang.org&amp;lt;/url&amp;gt;&lt;br /&gt;    &amp;lt;repositories&amp;gt;&lt;br /&gt;        &amp;lt;repository&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;name&amp;gt;Scala-tools Maven2 Repository&amp;lt;/name&amp;gt;&lt;br /&gt;            &amp;lt;url&amp;gt;http://scala-tools.org/repo-releases&amp;lt;/url&amp;gt;&lt;br /&gt;        &amp;lt;/repository&amp;gt;&lt;br /&gt;    &amp;lt;/repositories&amp;gt;&lt;br /&gt;    &amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;        &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;scala-tools.org&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;name&amp;gt;Scala-tools Maven2 Repository&amp;lt;/name&amp;gt;&lt;br /&gt;            &amp;lt;url&amp;gt;http://scala-tools.org/repo-releases&amp;lt;/url&amp;gt;&lt;br /&gt;        &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;    &amp;lt;/pluginRepositories&amp;gt;&lt;br /&gt;    &amp;lt;dependencies&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;org.scala-lang&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;scala-library&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;2.7.2-rc2&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;3.8.1&amp;lt;/version&amp;gt;&lt;br /&gt;            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;    &amp;lt;/dependencies&amp;gt;&lt;br /&gt;    &amp;lt;build&amp;gt;&lt;br /&gt;        &amp;lt;plugins&amp;gt;&lt;br /&gt;            &amp;lt;plugin&amp;gt;&lt;br /&gt;                &amp;lt;groupId&amp;gt;org.scala-tools&amp;lt;/groupId&amp;gt;&lt;br /&gt;                &amp;lt;artifactId&amp;gt;maven-scala-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;                &amp;lt;executions&amp;gt;&lt;br /&gt;                    &amp;lt;execution&amp;gt;&lt;br /&gt;                        &amp;lt;goals&amp;gt;&lt;br /&gt;                            &amp;lt;goal&amp;gt;compile&amp;lt;/goal&amp;gt;&lt;br /&gt;                            &amp;lt;goal&amp;gt;testCompile&amp;lt;/goal&amp;gt;&lt;br /&gt;                        &amp;lt;/goals&amp;gt;&lt;br /&gt;                    &amp;lt;/execution&amp;gt;&lt;br /&gt;                &amp;lt;/executions&amp;gt;&lt;br /&gt;                &amp;lt;configuration&amp;gt;&lt;br /&gt;                    &amp;lt;sourceDir&amp;gt;src/main/java&amp;lt;/sourceDir&amp;gt;&lt;br /&gt;                    &amp;lt;jvmArgs&amp;gt;&lt;br /&gt;                        &amp;lt;jvmArg&amp;gt;-Xms64m&amp;lt;/jvmArg&amp;gt;&lt;br /&gt;                        &amp;lt;jvmArg&amp;gt;-Xmx1024m&amp;lt;/jvmArg&amp;gt;&lt;br /&gt;                    &amp;lt;/jvmArgs&amp;gt;&lt;br /&gt;                &amp;lt;/configuration&amp;gt;&lt;br /&gt;            &amp;lt;/plugin&amp;gt;&lt;br /&gt;        &amp;lt;/plugins&amp;gt;&lt;br /&gt;    &amp;lt;/build&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Let's analyse this a bit.   First off, all pom files consist of a "project" xml element.  This encompases the entire xml document.   The modelVersion element is always the same and is required for maven2 projects.  Here's some simple descriptions of the other elements:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;groupId - This corresponds to the inverted domain-name of the project.  Although you could use any arbitrary value, it's recommended to use your company domain name here&lt;br /&gt;    &lt;li&gt;artifactId - This is a unique id for the project (within the group).  This name will be used when creating jar/war/ear files.&lt;br /&gt;    &lt;li&gt;version - This represents the current version of the project.  More details later&lt;br /&gt;    &lt;li&gt;name - This is the human-readable name of the project.&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;url -This is the url for the project website.&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;packaging - This defines the "style" of project your building (e.g. ear, jar, war, etc.).  For more information on packaging, check out the respective plugins (maven-jar-plugin, maven-war-plugin, etc.)&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;dependencies - Specifies the dependencies of the project.  This will be materialized from any defined maven repositories.  More details later&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;repositories - Specifies alternative locations for maven to look when materializing dependencies.&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;pluginRepositories - Specifies alternative location for maven to look when materializing build plugins&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;build - Specifies configuration on *how* to build the project&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;reports - Specifies configuration on *what* reports to generate for the project&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt; &lt;br /&gt;&lt;span style="font-weight:bold;"&gt; Default Directory Layout&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Maven projects have default layouts defined by a combination of the maven super-pom and any build-plugins you have declared.   These defaults are customizable, but it is generally recommended to use the convention.  (The more you deviate the more XML you need to write).  Here is a sample project layout with links to descriptions on which maven plugins are responsible for which directories and how you can override the defaults.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre&gt;&lt;br /&gt;project/&lt;br /&gt;   pom.xml   -  Defines the project&lt;br /&gt;   src/&lt;br /&gt;      main/&lt;br /&gt;          java/ - Contains all java code that will go in your final artifact.  &lt;br /&gt;                  See &lt;a href="http://maven.apache.org/plugins/maven-compiler-plugin/"&gt;maven-compiler-plugin&lt;/a&gt; for details&lt;br /&gt;          scala/ - Contains all scala code that will go in your final artifact.  &lt;br /&gt;                   See &lt;a href="http://scala-tools.org/mvnsites/maven-scala-plugin/"&gt;maven-scala-plugin&lt;/a&gt; for details&lt;br /&gt;          resources/ - Contains all static files that should be available on the classpath &lt;br /&gt;                       in the final artifact.  See &lt;a href="http://maven.apache.org/plugins/maven-resources-plugin/"&gt;maven-resources-plugin&lt;/a&gt; for details&lt;br /&gt;          webapp/ - Contains all content for a web application (jsps, css, images, etc.)  &lt;br /&gt;                    See &lt;a href="http://maven.apache.org/plugins/maven-war-plugin/"&gt;maven-war-plugin&lt;/a&gt; for details&lt;br /&gt;     site/ - Contains all apt or xdoc files used to create a project website.  &lt;br /&gt;             See &lt;a href="http://maven.apache.org/plugins/maven-site-plugin/"&gt;maven-site-plugin&lt;/a&gt; for details       &lt;br /&gt;     test/&lt;br /&gt;         java/ - Contains all java code used for testing.   &lt;br /&gt;                 See &lt;a href="http://maven.apache.org/plugins/maven-compiler-plugin/"&gt;maven-compiler-plugin&lt;/a&gt; for details&lt;br /&gt;         scala/ - Contains all scala code used for testing.   &lt;br /&gt;                  See &lt;a href="http://scala-tools.org/mvnsites/maven-scala-plugin/"&gt;maven-scala-plugin&lt;/a&gt; for details&lt;br /&gt;         resources/ - Contains all static content that should be available on the &lt;br /&gt;                      classpath during testing.   See &lt;a href="http://maven.apache.org/plugins/maven-resources-plugin/"&gt;maven-resources-plugin&lt;/a&gt; for details&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Although the above represents the default layout for most scala projects, every maven plugin used could bring in its own "convention" for where it would like to see code.  An example of this is that the gmaven plugin for groovy expects to find groovy source code in src/main/groovy and src/test/groovy (similar to the scala plugin). &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Build Lifecycle&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The maven build lifecycle is made up of "phases" and "goals".  A "goal" is a various action defined by a plugin.  Examples include scala:compile, jetty:run-war, jboss:deploy and (the one you should be familiar with) archetype:generate.   Goals are specific to a particular maven plugin and perform a single operation.  Phases on the other hand are more abstract ideas, and represent particular points in a standard build system.   Here's a listing of some of the phases for a maven build (taken from &lt;a href="http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html"&gt;here&lt;/a&gt;):&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;    &lt;li&gt;validate - validate the project is correct and all necessary information is available&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;compile - compile the source code of the project&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;package - take the compiled code and package it in its distributable format, such as a JAR.&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;integration-test - process and deploy the package if necessary into an environment where integration tests can be run&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;verify - run any checks to verify the package is valid and meets quality criteria&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;install - install the package into the local repository, for use as a dependency in other projects locally&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;deploy - done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;In reality, there are many more phases defined.  For a complete listing, &lt;a href="http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference"&gt;read here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When operating maven on the command line you can type "mvn" plus a list of goals and/or phases.   These will be executed in the order defined.   Some phases may depend on other phases, such that they do not need to be specified.   For example, package depends on test.   This means you cannot package your software unless all your tests pass, and packaging will always attempt to build.   When specifying goals on the command line, the goal will execute immediately with no dependencies.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Build Plugins&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One of the great features of maven is that there's a build plugin for almost any activity required in a Java/Scala project.   These plugins are defined in the project/build/plugins section of the pom.  Most build plugins automatically attach their goals to appropriate build phases when used, however this is configurable at runtime.  For example, here is how we ask the scala:compile and scala:testCompile goals to automatically bind to their respective phases:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;    &amp;lt;build&amp;gt;&lt;br /&gt;        &amp;lt;plugins&amp;gt;&lt;br /&gt;            &amp;lt;plugin&amp;gt;&lt;br /&gt;                &amp;lt;groupId&amp;gt;org.scala-tools&amp;lt;/groupId&amp;gt;&lt;br /&gt;                &amp;lt;artifactId&amp;gt;maven-scala-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;                &amp;lt;executions&amp;gt;&lt;br /&gt;                    &amp;lt;execution&amp;gt;&lt;br /&gt;                        &amp;lt;goals&amp;gt;&lt;br /&gt;                            &amp;lt;goal&amp;gt;compile&amp;lt;/goal&amp;gt;&lt;br /&gt;                            &amp;lt;goal&amp;gt;testCompile&amp;lt;/goal&amp;gt;&lt;br /&gt;                        &amp;lt;/goals&amp;gt;&lt;br /&gt;                    &amp;lt;/execution&amp;gt;&lt;br /&gt;                &amp;lt;/executions&amp;gt;&lt;br /&gt;                ...&lt;br /&gt;            &amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Inside the execution block there's a (sometimes) option id element and a phase element.   The phase element can be used if you'd like to bind a goal to a different phase then it defaults too. As an example, I sometimes bind the jboss:undeploy goal to the package phase and the jboss:deploy goal to the install phase.  This way if my unit tests succeed, my application gets undeployed/redeployed right after packaging, and I only to call mvn install on the command line.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Dependencies&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One of the powerful features of maven is declarative dependencies.  Maven allows projects to declare what dependencies they have, and will automatically materialize those dependencies (including transitive dependencies).  Maven dependency declaration looks like this:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;   &amp;lt;dependencies&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;org.scala-lang&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;scala-library&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;2.7.2-rc2&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;3.8.1&amp;lt;/version&amp;gt;&lt;br /&gt;            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;    &amp;lt;/dependencies&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Each dependency consists of several items:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;    &lt;li&gt;groupId - The group of the dependency to rely on&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;artifactId - The artifact in the group to rely on&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;version - The version of the dependency to rely on&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;scope - The "scope" of the dependency. Defaults to compile (more details later)&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;packaging - The packaging for the dependency.  Defaults to jar (e.g. jar, war, ear)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;The default maven repository has a website that allows you to search for dependencies called &lt;a href="http://mvnrepository.com"&gt;http://mvnrepository.com&lt;/a&gt;.  Most open source projects are available either via the "central" maven repository and a separately hosted maven repository (e.g. jboss host's their own repository).&lt;br /&gt;&lt;br /&gt;Dependencies in maven have scope.  The scope determines when/where the dependency will show up in a classpath.  Here are the commonly used scopes:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;    &lt;li&gt;compile - The dependency is available when compiling/running/testing the project and as a transitive dependency&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;runtime - The dependency is available when running/testing but not for compilation.  Runtime dependencies show up as transitive dependencies.&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;test - The dependency is available during testing phases, but not compilation or (non-testing) runtime.  Test dependencies do not show up as transitive dependencies&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;provided - The dependency is available during compilation, but not runtime.  e.g. You expect the servlet-api will be provided by a servlet container and therefore should be a "provided" dependency&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;More information (and scopes) is available &lt;a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Pom Inheritance&lt;/span&gt;&lt;br /&gt;The Second nicest feature of maven is pom-file inheritance.  Pom file inheritance works similarly to how single-inheritance works in an OO language.  The child POM inherits all configuration items of its parent, and can override/extend them with its own configuration.&lt;br /&gt;&lt;br /&gt;This is done through specifying a pom with a packaging of "pom", and then using the "parent" tag in a child project.  This can greatly reduce the amount of configuration done in "child" projects  (Often times my child project poms only specify their parent and their artifact/group/version triplet).&lt;br /&gt;&lt;br /&gt;I've posted about this before when talking about &lt;a href="http://suereth.blogspot.com/2008/05/not-gaven-not-graven-itsgmaven.html"&gt;GMaven&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;A child groovy project to the above pom would look like the following:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0"&lt;br /&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&amp;gt;&lt;br /&gt; &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt; &amp;lt;groupId&amp;gt;com.blogspot.suereth&amp;lt;/groupId&amp;gt;&lt;br /&gt; &amp;lt;artifactId&amp;gt;groovy-child&amp;lt;/artifactId&amp;gt;&lt;br /&gt; &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt; &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt; &lt;br /&gt; &amp;lt;parent&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;com.blogspot.suereth&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;groovy-parent&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt; &lt;br /&gt; &amp;lt;/parent&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This behavior is usually associated with multi-module projects, but that discussion is beyond the scope of this article.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Going Further&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This article is only designed to help you take your first steps towards using maven as your build environment.  There are more advanced topics that can greatly help your efforts of creating a build system.  Some of these include&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;    &lt;li&gt;Multi-module projects&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Profiles&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Settings.xml&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Setting up your own Maven Repository (and/or Proxy)&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Deploying artifacts&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Project reporting&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;I'm hoping to provide some more new-user documentation for the following in the near future.  For now, I'd recommend what most good maven-build-experts use for information: google.com and maven.apache.org&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-2449857706733384647?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/2449857706733384647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=2449857706733384647' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2449857706733384647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/2449857706733384647'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/10/maven-for-beginners.html' title='Maven For Beginners'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-7908416900251946666</id><published>2008-10-23T22:14:00.005-04:00</published><updated>2008-10-23T22:47:45.342-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JeOS'/><category scheme='http://www.blogger.com/atom/ns#' term='virtual appliance'/><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Virtual Appliance - Not a Toaster on Second Life</title><content type='html'>This posting is going to outline what a virtual appliance is.  This touches on what I do at work enough to give you a hint of some of the neat new things coming down the line.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt; No really, It's not a toaster... or a coffee maker&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So what is a virtual appliance?  A virtual appliance is a virtual machine that can be distributed (like any file) and deployed onto some hypervisor (a server that runs virtual machines).  Because a virtual appliance is an entire virtual machine, the appliance developer has control of the entire aspect of the machine, from operating system to window themes to startup procedures.  ***Not only could one use some custom operating system, one could perform more interesting OS integration without worrying about "cross-platform compatability".  Imagine buying a server that could initally be running a VM with your DNS and Email, and then repurpose it to dedicated indexing/search web interface. &lt;br /&gt;&lt;br /&gt;A few other interesting things to note about virtual appliances involve web hosting and choice of operating systems.  It is now feasible for a web host to simply provide some hypervisor (virtual server) and give you a virtual machine on this server.  You can then customize the machine however you want (under the resource restrictions the hosting service provides).  The host can control how much CPU/RAM/Network they allocate to your machine and enforce it in the hypervisor.  You can control almost every other aspect of your machine.  I know a lot of web hosting services have already started adopting this model.&lt;br /&gt;&lt;br /&gt;Another intersting thing you do on a virtual appliance is install any kind of (or no) operating system.  Many Linux distributions are starting to offer "virtualization optimized" packages (e.g. Ubuntu's JeOS, rPath's JeOS and Red Hat's (not released) &lt;a href="#two"&gt;Appliance Operating System&lt;/a&gt; [AOS]).  [JeOS =&gt; Just Enough Operating System, a term coined (AFAIK) by VMWare).  These JeOS products could greatly improve performance of your virtual appliance.  I predict that in the future we'll see more custom distributions, kernels or entire operating system stacks.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Early Brew&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the 90's MIT was doing research into something they called the "&lt;a href="#one"&gt;Exokernel&lt;/a&gt;".   The idea behind an exokernel was one step beyond micro-kernels: The kernel should only multiplex resources on a machine.  The idea was neat, and they experimented with a webserver they called "Cheetah".  Cheetah implemented its own memory management to reduce the os-abstraction-overhead of server static content.  Cheetah was able to gain an order-of-magnitude in performance by marking and passing memory loaded with file contents directly to the NIC without having to be copied to and from user-space.  The exo kernel failed in other areas, mainly in that it tried to multiplex host resources *separately* for all "processes".  I remember watching the ExOS library (a POSIX-as-a-shared-library implementation) fly together, but the file system really started caused some trouble.   It was hard to share a disk across operating systems without imposing some kind of filesystem on them all.&lt;br /&gt;&lt;br /&gt;Virtualization is very similar to the ExOS idea.  It multiplexes physical resources across many virtual machines.  The big difference here is in the fundamental unit of execution: For ExOS it was still a Process, however for the Hypervisor it's a "Machine".  This difference in fundamental unit is what has made virtualization so popular, however it doesn't mean we have to give up some of the things we've learned from the exokernel.  We can still implement an OS that is highly tuned for some specific purpose (almost like an embedded device).  However, instead of compiling for a particular architecture, we compile to the x86-virtualized-architecture.  We can back our order-of-magnitude performance gain for hosting static content.  The question remains, what is the cost of the extra-layer of abstraction that virtualization brings?  With no hard data, I can't answer this question.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Burnt Edges&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Because using virtual machines give so much new flexibility to how applications are developed, a whole new host of issues also creep in.  The biggest of these is how to generate these virtual appliances in the first place.  What I've seen most often in "How To" documents (Amazon EC2's for example) is that you should start with a base OS install and begin to customize your appliance until it suits you.  Being a virtual machine, you can then clone this machine to distribute to clients (or yourself).  This works great, but is tougher to automate, and upgrade.&lt;br /&gt;&lt;br /&gt;One thing that can help in this process is the "snapshot" feature provided by some vm vendors.  This means you can set up a virtual machine how you like it, but without most of your software installed.  Then when doing a distribution, you install your software, clone your machine, and revert the "template" back to a pre-install state. &lt;br /&gt;&lt;br /&gt;Although this gives you a way of creating nearly infinite numbers of virtual appliances, it still leaves something to be desired (automation).  I've noticed that as virtual appliances become more prevalent a few companies have begun offering tools to help manage this.  rPath &lt;a href="#three"&gt;rBuilder&lt;/a&gt; is one such product.  It uses a completely new packaging system (Conary) and its own JeOS Linux Distro.&lt;br /&gt;&lt;br /&gt;If you're more into completely free (well, pay for service), Ubuntu also recently posted some documentation for their open-source JeOS"&lt;a href="#four"&gt;JeOSVMBuilder&lt;/a&gt;". &lt;br /&gt;&lt;br /&gt;Anyway, The virtualization market is pretty exciting times.  Migrating to virtualization can provide a *lot* of flexibility to your infrastructure.  Use completely open-source software, I've been able to set up a "development server" complete with source control, project website, issue tracking, etc. AND nightly backups are as simple as copying a file to a USB disk.  If you're interested in doing the same, I'd recommend looking into VirtualBox.  If I can find the proper place to host (and time to clean it up), I may host my Ubuntu JeOS development server  (Apache2 + Tomcat + Archiva + Hudson + Trac + SVN). &lt;br /&gt;&lt;br /&gt;As a side note, the more I've seen of GIT the more I like it.  Given some time (once again, hard to come by),  I'm thinking of making the dev server be flexible enough to create new projects with svn, Hg or git.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="one"&gt;&lt;/a&gt;[1] &lt;a href="http://pdos.csail.mit.edu/exo.html"&gt;MIT Exokernel Operating System&lt;/a&gt;&lt;br /&gt;&lt;a name="two"&gt;&lt;/a&gt;[2] &lt;a href="http://www.redhat.com/solutions/aos/"&gt;Red Hat Appliance Operating System&lt;/a&gt;&lt;br /&gt;&lt;a name="three"&gt;&lt;/a&gt;[3] &lt;a href="http://www.rpath.com/corp/products/rbuilder"&gt;rBuilder&lt;/a&gt;&lt;br /&gt;&lt;a name="four"&gt;&lt;/a&gt;[4] &lt;a href="https://help.ubuntu.com/community/JeOSVMBuilder"&gt;JeOSVMBuilder&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-7908416900251946666?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/7908416900251946666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=7908416900251946666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/7908416900251946666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/7908416900251946666'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/10/virtual-appliance-not-toaster-on-second.html' title='Virtual Appliance - Not a Toaster on Second Life'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-8602452978566965094</id><published>2008-10-06T18:21:00.001-04:00</published><updated>2008-10-09T20:13:15.397-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='dependency injection'/><category scheme='http://www.blogger.com/atom/ns#' term='statics'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='singleton'/><title type='text'>Singletons are for Simpletons (Statics =&gt; Fail)</title><content type='html'>&lt;span style="font-style:italic;"&gt;Clarification:  After having many IM chats about this post, I thought I'd write a minor clarification.  In this post I outline a very dogmatic approach to avoiding Singletons in the attempt to ease unit testing.  In real life, I'm far too practical to completely avoid singletons. As a rule of thumb, I think they are avoidable and you can simplify development by not having them.  Next time you're thinking of using singletons, think: "If statics did not exist and I needed this functionality, would I pass this class into every class in my application?".  Hopefully it'll help you reach a common ground between over-use and never-use.  This post is an attempt to sway statics/singleton-heavy users over to a middle-ground of sorts.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Some of you may be wondering why I'm writing about fundamentals of mechanical engineering.  Actually, This posting is about statics in programming.  Other words sometimes used for statics are globals, singletons or pure evil.  The goal of this post is to show why you should avoid statics/globals/singletons in your own code, and what you can gain by doing so.&lt;br /&gt;&lt;br /&gt;Statics are pretty tempting when first learning Java.  Sometimes it's easier to just make something static then figure out how/who needs to receive functionality from a particular class.  Singletons are even more dangerous in that they grant the illusion of have a  real class while not really buying you an amazing amount of power. (I guess inheritance counts...)&lt;br /&gt;&lt;br /&gt;Let's see a typical Java Singleton in action:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;package com.blogspot.suereth.statics.suxorz&lt;br /&gt;&lt;br /&gt;public class SimpletonSingleton {&lt;br /&gt;&lt;br /&gt;   private static SimpletonSingleton instance = new SimpletonSingleton();&lt;br /&gt;   //This appears like a non-static variable huh?  Even looks testable I bet...&lt;br /&gt;   private ImportantInterface memberOne;&lt;br /&gt;&lt;br /&gt;   private SimpletonSingleton() {&lt;br /&gt;         memberOne = lookUpImportantInterface(memberOne);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   //Helper methods, all synchronized of course&lt;br /&gt;   ...&lt;br /&gt;   public static SimpletonSingleton getInstance() {&lt;br /&gt;        return instance;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Rather than diverge into the issues surrounding java singletons and classloaders etc., let's point out a few real issues with this code.  I see two major issues &lt;ol&gt;&lt;li&gt;It appears clever&lt;/li&gt;&lt;li&gt;It's not&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;In terms of 1, I've seen and done a lot of "clever" things with singletons.  It's amazing how "easy" you can make developing an application.  Sure, create a database abstraction that lets you pull in all sorts of things from your database into your application.  I remember my days of CORBA in C++ where I created an "OrbAccess" singleton.  That was my genius way of not having tons of references passed in the constructors of every class. In C++ the overhead of managing that much information became painful, even with multiple inheritance.  (I toyed with the idea of a "ORBHelper" virtual base class that just took in an ORB and gave you helper methods).  The problem here is that once you make something a static/global/singleton you lose control of access of the object, but more importantly you lose control of composition of your software.&lt;br /&gt;&lt;br /&gt;The second point revolves around this.  Object-Oriented software is much more about composition than inheritance.  More importantly re-usability and testing become FAR easier with composition.&lt;br /&gt;&lt;br /&gt;Look at the above code.  Now image how we go about testing it.  Here's a few scenarios:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;"There's Only one of these per application so I'll make it a Singleton" Singleton&lt;/b&gt; - If only I hadn't seen these in the wild... I wouldn't even mention them.  Just because you only want one instance of a class is *NO* reason to make it a formal singleton (like the above).  The main problem with this is you lose access to when the object is created, and therefore the *arguments* to the singleton.  It is now harder to compose your application.  Good Job!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Data-Layer Access Singleton&lt;/b&gt; - We want a singleton that will manage all our access to the database.  This way all our JDBC and queries are in one place! great.  The "lookUpImportantInterface" method actually pulls in some .properties file and wires in some way of grabbing connections or hibernate sessions, or &lt;i&gt;:::insert framework here:::&lt;/i&gt;.  Slick huh?  Alright, so now let's say I want to test this singleton.  I now have to abstract out either the entire JDBC API or some other layer on top of it (ugh).  WORSE! If I want to test classes that *use* the singleton, I &lt;b&gt;STILL&lt;/b&gt; have to abstract out the entire JDBC API, or bootstrap a database, or some other nonesense.  Also, this singleton winds up getting changed any time I want to grab some new type of data out of the database.  Isn't this one of the code smells from Martin Fowler's "Refactoring"?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Factory Singleton&lt;/b&gt; - Perhaps this is cheating (since the Data-Layer Access Singleton could be considered a Factory singleton).  The basic premise is I want a factory that will generate instances of classes.  This way I don't have to remember all the crazy sub-classes, I can just change implementations based on arguments and overloaded methods.  YAY!  The underlying problem here is how you go about testing *users* of the Factory singleton.  You need to be careful about how/when you go about creating and using the objects.  If you've designed your software such that a 3rd party does the composition (ala dependency injection), then you can get away with a Factory Singleton AND have testability.  If you make the factory calls yourself in a "user" class, you can no longer isolate your testing of that user class, and have to mock whatever framework the Factory Singleton uses when testing &lt;b&gt;its&lt;/b&gt; users.  This can be difficult, if not impossible if you are not the author of the Factory Singleton.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Resource Caching Singleton (or the Flyweight Singleton)&lt;/b&gt; - Suffers from all the same issues as the Factory Singleton PLUS you have to write massively ugly threading code with statics...&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Event Queue Singleton&lt;/b&gt; - As these are usually used in GUI applications where you can only have one thread interacting with widgets, I don't have much negative here.  It's already a GUI so testing is hard.  Go crazy and write bad code.  I'll go work on the server :)  As an aside, I think the days of single-threading GUI event loops are coming to an end.  Multi-core is going to force their hands.  Perhaps when the languages catch up, the core libraries will be next.  For other uses, I would rather see instantiations of event queues that get passed into objects than singletons personally.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;X-Pool Singleton&lt;/b&gt; - Seems great right?  Need a socket, grab one from the pool.  Need an inflatable alligator? It's in the pool.  Anyone can access the pool, but it enforces fairness right? Oh... you mean it doesn't know who's using it?  Well, I'll just have my class call the "get_low_priority" method.  Wait, nevermind, *my* class is important.  *YOU* call the low priority method.  How does the pool get instantiated? OH, it needs to know how to start itself.  What about testing?  Well I'll need to have a mock-configuration for every test I run on users of the pool... Not so fun anymore...  MAYBE I'll just make  "get_object" interface and pass it in to the constructor of my object.  That way I can change how it works when I compose my application (for testing or production or otherwise).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Utility Singleton&lt;/b&gt; - So this is perhaps the most useful of singletons.  What you're actually doing is creating a bunch of pure functions.  In C++ you wouldn't even need to place them in a class, just a namespace.  As long as the functions are pure (no mutating state), This singleton becomes easily testable.  &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you can see, although there are some *ok* usages of singletons, the vast majority of usages detract from locality of code and testability.  I've worked on a lot of projects where automated unit testing is thrown out, not because there's no time, but because the design/architecture of the code makes automated unit testing hard/costly.  My argument is that (at least in modern languages), there's no reason to throw testability out for these static/singleton usage patterns.  I can use this newfangled "Dependency Injection" technique and *still* have slick code.&lt;br /&gt;&lt;br /&gt;Am I interfacing with a JmsQueue?  Make a simple abstraction:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;interface JmsQueue {&lt;br /&gt;   public void sendMessage(Serializable msg) throws CommunicationError, FatalError;&lt;br /&gt;   public void addMessageListener(MessageListener ml);&lt;br /&gt;   public void addErrorHandler(KeepAliveErrorHandler el);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now I can pass a mock instance of this interface into all my classes that send JMS Messages.  I can even make sure the messages sent are correct using my mock.  I can even test communication errors using my mock, and make sure my business logic is designed to handle it.&lt;br /&gt;&lt;br /&gt;For JMS Receivers implementing the MessageListener interface I should be able to test that interface directly. &lt;br /&gt;&lt;br /&gt;&lt;i&gt;DON'T Fall into the trap of wiring "Listener" classes into the "Listened" objects during the "Listener" class's constructor.  Although it may seem clever, it means that you now need to abstract out the *entire* "listened" object, instead of just calling methods on the listener class.  It's better to give yourself the freedom of composition for later enhancements.  What if you wanted to load-balance your listeners?  What if you wanted to consolidate several listeners?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In conlusion... Avoid singletons if possible.  Save "wiring" your classes until later.  You can get something working quicker if you can test it out IMMEDIATELY vs. waiting for your infrastructure/architecture to fall in place.  Think of coding as two phases: &lt;ol&gt;&lt;li&gt;Single Class Design, Implementation and Testing&lt;/li&gt;&lt;li&gt;Composition/Architecture of classes and Integration Testing&lt;/li&gt;&lt;/ol&gt;  In practice don't separate these too much, as you'll design some really bad classes. However it's a good logical distinction.&lt;br /&gt;&lt;br /&gt;Also keep this in mind.  Dependency injection does not mean Spring or Guice or J2EE.  Dependency injection can be accomplished via "Composer" classes as I like to call them.  These are the "Main" classes of an application, that can just instantiate objects and pass them into constructors.  This is the guy who sets up an environment for the classes to run in.  Your JUnit tests are 'composer' classes.  They set up a much smaller execution environment, but they are setting one up.  Your main application could have multiple or one large composer class, or it could hide and use a "generic" one that reads "xml" or "annotations".  In any case there *is* a composer class that creates your execution environment for you.  Break you application into "users" and "composers" and testing will be much easier on you.  Make sure your composer classes don't contain too much logic and you should be on your way to an easier-to-maintain code base.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-8602452978566965094?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/8602452978566965094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=8602452978566965094' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8602452978566965094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/8602452978566965094'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/10/singletons-are-for-simpletons-statics.html' title='Singletons are for Simpletons (Statics =&gt; Fail)'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-3685541979347823464</id><published>2008-09-28T10:49:00.001-04:00</published><updated>2008-10-24T10:26:15.727-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='db:migrate'/><category scheme='http://www.blogger.com/atom/ns#' term='migrate'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='dsl'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Using Scala for Domain-Specific-Languages</title><content type='html'>In this post, I'm going to attempt to create something similar to Ruby on Rails (or rake's) db:migrate scripts in Scala.  I'm not going to actually implement features, just show how one can go about constructing a DSL in the Scala language.  This is a learning process for me, so please excuse some mistakes I may make, and hopefully I can correct them in future posts.&lt;br /&gt;&lt;br /&gt;For a quick over-view of what the db:migrate scripts provide in Rails:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Convienient language-based syntax for creating/modifying/deleting tables&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Versioning of the Database API&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Convention for defining scripts to perform migrations between various versions&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I've seen proprietary methods like db:migrate implemented at various companies, so I don't think it's anything new.  The nice thing about rails db:migrate is that you can remain db-agnostic for simple cases AND creating a new migration is pretty easy.  I'd like to keep the same conventions in scala.&lt;br /&gt;&lt;br /&gt;To begin with, we're going to define a parent class (actually a trait) for all database migration scripts to inherit from.  In rails, I believe it's called ActiveRecord::Migration.  For our purposes, we'll call it Migration.&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;package com.blogspot.suereth.dbmigrate&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* This trait is a common parent for all migration scripts.  Each migration represents a version.&lt;br /&gt;*/&lt;br /&gt;trait Migration {&lt;br /&gt; def upgrade(implicit ctx : MigrationContext)&lt;br /&gt; def downgrade(implicit ctx : MigrationContext)&lt;br /&gt; def version : Int  //TODO - Figure out how we're really going to do versions.&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The above trait is very similar to the Rails version.  The three methods do the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;upgrade - Migrate the database from the previous version to "this" version&lt;/li&gt;&lt;br /&gt;&lt;li&gt;downgrade - Migrate the database from "this" version to the previous version&lt;/li&gt;&lt;br /&gt;&lt;li&gt;version - "this" version for the migration.  i.e. upgrade should leave me at version X&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Already I'm introducing the implicit argument keyword here.  We'll get to why this is useful later, but for now just pretend like we're passing in a MigrationContext object that can be used to perform database manipulations.  We can assume the MigrationContext will handle all of our database transactions in a reasonable fashion.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For now, let's focus on defining tables in our DSL.  What we'd like to see is something like the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class Migration1 extends Migration {&lt;br /&gt; import MigrationDSL._&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; def upgrade(implicit ctx : MigrationContext) {&lt;br /&gt;  &lt;br /&gt;   create_table('user) {&lt;br /&gt;     tbl =&gt;&lt;br /&gt;       tbl has_column 'user_id as classOf[Int] default 0 primaryKey()&lt;br /&gt;       tbl has_column 'user_name as classOf[String] not_null()&lt;br /&gt;   }   &lt;br /&gt;&lt;br /&gt; }&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So  how do we get here?  We'll let's do a top-down approach.  First, there's the syntax: &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;create_table('user) { tbl =&gt; ... }&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This looks like (and is) a function call.  We have two options for where to place it.  We can place it in the Migration trait (which I'm reluctant to do) or we can place it into the MigrationDSL object (see the import above).  We're going to place it in MigrationDSL.  Here's our first cut at the create_table function: &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;object MigrationDSL {&lt;br /&gt;  def create_table[A](name : Symbol)(creatorScript : TableCreator =&gt; A) = {&lt;br /&gt;    //TODO - Implement&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Alright, so now after importing MigrationDSL._ we can write create_table('symbol) { tbl=&gt; } anywhere we want.&lt;br /&gt;&lt;br /&gt;There's two things I don't like about this.  One is that we're placing implementation into our MigrationDSL.  I'd rather keep the DSL abstract, so we can implement it however we feel like.  We should be using the MigrationContext trait/interface here.  The other complaint is that we can write create_table from anywhere as long as we import MigrationDSL._.  We want to only be able to use this in the context of a migration.  Let's try to have MigrationDSL forward its method call to a migration context like so:   &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;object MigrationDSL {&lt;br /&gt;  def create_table[A](name : Symbol)(creatorScript : TableCreator =&gt; A)(implicit ctx : MigrationContext)  = ctx.createTable(name.toString)(creatorScript)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Once again I'm using the implicit argument keyword.  What's it doing here?  Well this time I'm using it so that when you call the create_table method, you either need to explicitly pass in a MigrationContext &lt;b&gt;or&lt;/b&gt; have one available for implicit usage.  If you remember when we defined the Migration trait, the upgrade/downgrade methods both take in an implicit MigrationContext.  This means that within an upgrade/downgrade method, there is a MigrationContext implicitly available (and therefore you don't have to specify it).  It's the last parameter of the last parameter-set just so the compiler can use it implicitly.  We're back to having our desired syntax, AND we're still delegating all calls through the MigrationContext.&lt;br /&gt;&lt;br /&gt;Now we need to define what the MigrationContext trait looks like (at least so that it has the createTable method.  It's going to look very much like the earlier create_table that was on our MigrationDSL object.  Here's the new MigrationContext: &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;trait MigrationContext {&lt;br /&gt;  def createTable[A](name : String)(creatorScript : TableCreator =&gt; A) : A&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Notice that the method is completely abstract.  We've now divorced our DSL in such a way that someone simple needs to implement a MigrationContext for our DSL.&lt;br /&gt;&lt;br /&gt;The next item we'd like to implement are the column definition lines: &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt; tbl has_column('user_id) as classOf[Int] default 0 primaryKey()&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;As we haven't defined the TableCreator type yet (which is what our creatorScripts are accepting), let's define it and add the "has_column" method:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt; trait TableCreator { &lt;br /&gt; def has_column(name : Symbol) : ColumnCreator&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Once again I'm keeping everything as pure-abstract Traits.  We'll leave implementation as an exercise to the reader.  As you can see the has_column method take in a symbol and returns a ColumnCreator.  We're going to have to put the rest of our column DSL into the ColumnCreator class.  First, let's tackle the "as" method.  All columns need to have a type associated.  This is something we'd like to require, however we'll leave that as an implementation detail for the time being.  &lt;i&gt;If anyone has a suggestion for how to require this method be called at compile time, please let me know!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Let's look at the ColumnCreator trait: &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;trait ColumnCreator {&lt;br /&gt; def as[A](clazz : Class[A]) : ColumnCreator2[A]&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This trait defines one method (as) and returns a completely different (typed) ColumnCreator2 type.  This is our way of guaranteeing that (a) users always define types for column and (b) we have a valid type before allowing the default function of our DSL to be called.  So after this call, we have a valid column that could be created in a database table.  However for all our configuration options, we'll have to do something with the ColumnCreator2[A] trait.  Here's what it looks like for me: &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;trait ColumnCreator2[A]&lt;br /&gt;{&lt;br /&gt; def default(value : A) : ColumnCreator2[A]&lt;br /&gt; def primaryKey() : ColumnCreator2[A]&lt;br /&gt; def not_null() : ColumnCreator2[A]&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Because ColumnCreator2 is typed, we can now enforce type-safety for the column's default value.  That means &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt; tbl has_column('MyCol) as classOf[Int] default ""&lt;/pre&gt;&lt;/div&gt; will fail to compile.&lt;br /&gt;The only downside to this DSL (which I'm trying to determine  a way around) is that primaryKey and not_null attributes of a column both require a () to compile within scala.  This is a very minor downside, but perhaps I'll determine a clever way around it in the future.&lt;br /&gt;&lt;br /&gt;The next bit I'd like to show is some syntax to add foreign keys to our tables.  Here's another potential migration usage example:&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class Migration2 extends Migration {&lt;br /&gt; import MigrationDSL._&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; def upgrade(implicit ctx : MigrationContext) {&lt;br /&gt;  &lt;br /&gt;   create_table('roles) {&lt;br /&gt;     tbl =&gt;&lt;br /&gt;       tbl has_column 'user_id as classOf[Int]&lt;br /&gt;       tbl has_column 'role as classOf[String] not_null()&lt;br /&gt;       tbl has_foreign_key 'fk_user_id on 'user_id references 'user_id on 'user&lt;br /&gt;   }&lt;br /&gt;   ...   &lt;br /&gt; }&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Notice we've added the "has_foreign_key" syntax  here.  The above syntax should create a foreign key titled "fk_user_id" from column user_id on the roles table to the column user_id on the user table.&lt;br /&gt;Once again, this looks like (and is) a function call on the TableCreator trait.  Here's our new Trait definition: &lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;trait TableCreator { &lt;br /&gt; def has_column(name : Symbol) : ColumnCreator&lt;br /&gt; def has_foreign_key(name : Symbol) : FkConstraintCreator1&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Now to define the FkConstraintCreator traits.  Because we need to ensure specific ordering of the DSL, we're basically defining a series of traits the expose the correct methods in the appropriate order.  Here they are:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;trait FkConstraintCreator1 {&lt;br /&gt; def on(name : Symbol) : FkConstraintCreator2&lt;br /&gt;}&lt;br /&gt;trait FkConstraintCreator2 {&lt;br /&gt; def references(columnName : Symbol) : FkConstraintCreator3&lt;br /&gt;}&lt;br /&gt;trait FkConstraintCreator3 {&lt;br /&gt; def on(tableName : Symbol) : FkConstraintCreatorLast&lt;br /&gt;}&lt;br /&gt;trait FkConstraintCreatorLast {&lt;br /&gt; def on_delete(action : Symbol)&lt;br /&gt; def on_update(action : Symbol)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;With this series of FkConstraintCreators, we can now enforce a particular ordering of language in our DSL.  The nice part is that we can still define one FkConstraintCreator (or Builder) implementation that inherits from ALL the FKConstraintCreator traits.  This could help simplify our implementation while leaving the DSL staticly-type-safe.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In conclusion it was amazingly easy to define a somewhat rich DSL in Scala.  Perhaps in the future I'll write an implementation for the MigrationContext and contribute this code to Lift and/or Scala proper.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-3685541979347823464?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/3685541979347823464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=3685541979347823464' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/3685541979347823464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/3685541979347823464'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/09/using-scala-for-domain-specific.html' title='Using Scala for Domain-Specific-Languages'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-1112081557146118085</id><published>2008-09-25T23:18:00.000-04:00</published><updated>2008-09-25T23:39:26.177-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bootstrap'/><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><category scheme='http://www.blogger.com/atom/ns#' term='tasks'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Using Maven-Ant-Tasks instead of Ivy.</title><content type='html'>So recently I had the (clever?) idea to attempt to use the maven-ant-tasks to bootstrap an entire build of scala.  This could be a good way to jump-start existing ant users into the scala environment.  If not, at least it proved to me I have at least a basic understanding of what I'm using.&lt;br /&gt;&lt;br /&gt;So basically the build file is pasted below in its entirety.  The build file will:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Download the maven-ant-tasks jar file (2.0.9)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Create 2 files, one scala and one java&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Download the scala-library and scala-compiler from the maven-central repository&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Compile the scala and java code&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Create a jar file with the compiled code.  This jar file will have its Main-Class and Class-Path attributes set to allow easy usage&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Copy the scala-library into a local path that the "project" jar file expects.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;When finished, type: java -jar build/test-maven-in-ant.jar (or use \ in windows).  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The fun part about this build file was having it bootstrap ant-tasks via the maven task.  It wouldn't be hard to pull in the groovy task as well (which I plan to attempt given more free time).  Thanks to the latest scala feature of parsing java files, scala-groovy-java projects are now more easily accomplished.&lt;br /&gt;&lt;br /&gt;Anyway, without further ado... Here's the buildfile:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;project name="test-maven-in-ant" default="package.done" xmlns:artifact="urn:maven-artifact-ant"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;property name="root.dir" value="." /&amp;gt;&lt;br /&gt; &amp;lt;property name="sources.dir" value="${root.dir}${file.separator}src" /&amp;gt;&lt;br /&gt; &amp;lt;property name="build.dir" value="${root.dir}${file.separator}build" /&amp;gt;&lt;br /&gt; &amp;lt;property name="build.classes.dir" value="${build.dir}${file.separator}classes" /&amp;gt;&lt;br /&gt; &amp;lt;property name="lib.dir" value="${root.dir}${file.separator}lib" /&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;property name="maven.ant.tasks.jar" value="${lib.dir}${file.separator}maven-ant-tasks-2.0.9.jar"/&amp;gt;&lt;br /&gt; &amp;lt;property name="maven.ant.tasks.bootstrap.location" value="http://apache.inetbridge.net/maven/binaries/maven-ant-tasks-2.0.9.jar"/&amp;gt;&lt;br /&gt; &amp;lt;available property="maven.ant.tasks.jar.exists" file="${maven.ant.tasks.jar}"/&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;property name="package.name" value="${ant.project.name}.jar"/&amp;gt;&lt;br /&gt; &amp;lt;property name="package.location" value="${build.dir}${file.separator}${package.name}"/&amp;gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &amp;lt;!-- This will download the "latest version" of the maven-ant-tasks if needed --&amp;gt;&lt;br /&gt; &amp;lt;target name="bootstrap.maven.tasks" unless="maven.ant.tasks.jar.exists"&amp;gt;&lt;br /&gt;  &amp;lt;mkdir dir="${lib.dir}"/&amp;gt;&lt;br /&gt;  &amp;lt;get src="${maven.ant.tasks.bootstrap.location}" dest="${maven.ant.tasks.jar}"/&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- This will initialize all the maven ant tasks --&amp;gt;&lt;br /&gt; &amp;lt;target name="init.maven.tasks" depends="bootstrap.maven.tasks"&amp;gt;&lt;br /&gt;  &amp;lt;path &lt;br /&gt;   id="maven.ant.tasks.classpath" &lt;br /&gt;   path="${maven.ant.tasks.jar}" /&amp;gt;&lt;br /&gt;  &amp;lt;typedef &lt;br /&gt;   resource="org/apache/maven/artifact/ant/antlib.xml" &lt;br /&gt;   uri="urn:maven-artifact-ant" &lt;br /&gt;   classpathref="maven.ant.tasks.classpath" /&amp;gt; &lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;!-- This bootstraps the scala ant tasks from the maven repository and initializes them --&amp;gt;&lt;br /&gt; &amp;lt;target name="init.scala.tasks" depends="init.maven.tasks"&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;artifact:dependencies pathId="scala.tasks.classpath"&amp;gt;&lt;br /&gt;   &amp;lt;dependency groupId="org.scala-lang" artifactId="scala-compiler" version="2.7.2-rc2" scope="compile" /&amp;gt;&lt;br /&gt;   &amp;lt;remoteRepository id="scala-tools.repository" url="http://scala-tools.org/repo-releases" /&amp;gt;&lt;br /&gt;  &amp;lt;/artifact:dependencies&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;taskdef resource="scala/tools/ant/antlib.xml"&amp;gt;&lt;br /&gt;   &amp;lt;classpath refid="scala.tasks.classpath" /&amp;gt;&lt;br /&gt;  &amp;lt;/taskdef&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Initializes all the directories we need to build --&amp;gt;&lt;br /&gt; &amp;lt;target name="init.build.dirs"&amp;gt;&lt;br /&gt;  &amp;lt;mkdir dir="${build.classes.dir}" /&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Initializes the classpath for the project dependencies--&amp;gt;&lt;br /&gt; &amp;lt;target name="init.project.dependencies" depends="init.maven.tasks"&amp;gt;&lt;br /&gt;  &lt;br /&gt;  &amp;lt;artifact:dependencies pathId="project.classpath" filesetId="project.dependency.fileset"&amp;gt;&lt;br /&gt;   &amp;lt;dependency groupId="org.scala-lang" artifactId="scala-library" version="2.7.2-rc2" scope="compile" /&amp;gt;&lt;br /&gt;   &amp;lt;remoteRepository id="scala-tools.repository" url="http://scala-tools.org/repo-releases" /&amp;gt;&lt;br /&gt;  &amp;lt;/artifact:dependencies&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Initialize source code for compilation --&amp;gt;&lt;br /&gt; &amp;lt;target name="init.sources"&amp;gt;&lt;br /&gt;  &amp;lt;mkdir dir="${sources.dir}/test"/&amp;gt;&lt;br /&gt;  &amp;lt;echo file="${sources.dir}/test/IDoStuff.java"&amp;gt;package test;&lt;br /&gt;&lt;br /&gt;   public interface IDoStuff {&lt;br /&gt;    public void doStuff();&lt;br /&gt;   }&lt;br /&gt;  &amp;lt;/echo&amp;gt;&lt;br /&gt;  &amp;lt;echo file="${sources.dir}/test/ScalaDoStuff.scala"&amp;gt;package test&lt;br /&gt;&lt;br /&gt;   class ScalaDoStuff extends IDoStuff {&lt;br /&gt;     override def doStuff() : Unit = {&lt;br /&gt;       Console println "HAI"&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   object ScalaMain {&lt;br /&gt;     def main(args : Array[String]) : Unit = {&lt;br /&gt;       val tmp : IDoStuff = new ScalaDoStuff();&lt;br /&gt;       tmp.doStuff();&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;  &amp;lt;/echo&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &amp;lt;!-- Dummy target so we can add arbitrary init tasks --&amp;gt;&lt;br /&gt; &amp;lt;target name="init.done" depends="init.build.dirs,init.project.dependencies,init.scala.tasks,init.sources"&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;!-- Initial step for all compilation.  Marker --&amp;gt;&lt;br /&gt; &amp;lt;target name="compile.init" depends="init.done" /&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;!-- compiles Scala Code --&amp;gt;&lt;br /&gt; &amp;lt;target name="compile.scala" depends="compile.init"&amp;gt;&lt;br /&gt;  &amp;lt;scalac srcdir="${sources.dir}" destdir="${build.classes.dir}" classpathref="project.classpath" force="changed"&amp;gt;&lt;br /&gt;   &amp;lt;include name="**/*.scala" /&amp;gt;&lt;br /&gt;   &amp;lt;include name="**/*.java" /&amp;gt;&lt;br /&gt;  &amp;lt;/scalac&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;!-- Compiles java code, depends on scala --&amp;gt;&lt;br /&gt; &amp;lt;target name="compile.java" depends="compile.scala"&amp;gt;&lt;br /&gt;  &amp;lt;javac srcdir="${sources.dir}" destdir="${build.classes.dir}" source="1.5" target="1.5"&amp;gt;&lt;br /&gt;   &amp;lt;include name="**/*.java"/&amp;gt;&lt;br /&gt;   &amp;lt;classpath refid="project.classpath"/&amp;gt;&lt;br /&gt;   &amp;lt;classpath&amp;gt;&lt;br /&gt;    &amp;lt;fileset dir="${build.classes.dir}"&amp;gt;&lt;br /&gt;     &amp;lt;include name="**/*.class"/&amp;gt;&lt;br /&gt;    &amp;lt;/fileset&amp;gt;&lt;br /&gt;   &amp;lt;/classpath&amp;gt;&lt;br /&gt;  &amp;lt;/javac&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;!-- Marker for finishing the compilation phase --&amp;gt;&lt;br /&gt; &amp;lt;target name="compile.done" depends="compile.scala,compile.java" /&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;!-- Marker for package phase --&amp;gt;&lt;br /&gt; &amp;lt;target name="package.init" depends="compile.done"/&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;!-- copy our dependencies from maven's struture into our lib directory --&amp;gt;&lt;br /&gt; &amp;lt;target name="package.copy.dependencies" depends="package.init"&amp;gt;&lt;br /&gt;  &amp;lt;copy todir="${build.dir}/lib"&amp;gt;&lt;br /&gt;    &amp;lt;fileset refid="project.dependency.fileset" /&amp;gt;&lt;br /&gt;    &amp;lt;!-- This mapper strips off all leading directory information --&amp;gt; &lt;br /&gt;    &amp;lt;mapper type="flatten" /&amp;gt;&lt;br /&gt;  &amp;lt;/copy&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;!-- package our jar file --&amp;gt;&lt;br /&gt; &amp;lt;target name="package.jar" depends="package.init"&amp;gt;&lt;br /&gt;  &amp;lt;jar destfile="${package.location}" basedir="${build.classes.dir}"&amp;gt;&lt;br /&gt;   &amp;lt;include name="**/*.class"/&amp;gt;&lt;br /&gt;   &amp;lt;manifest&amp;gt;&lt;br /&gt;    &amp;lt;!-- Hacked for now --&amp;gt;&lt;br /&gt;    &amp;lt;attribute name="Main-Class" value="test.ScalaMain"/&amp;gt;&lt;br /&gt;    &amp;lt;attribute name="Class-Path" value="lib/scala-library-2.7.2-rc2.jar"/&amp;gt;&lt;br /&gt;   &amp;lt;/manifest&amp;gt;&lt;br /&gt;  &amp;lt;/jar&amp;gt;&lt;br /&gt; &amp;lt;/target&amp;gt;&lt;br /&gt; &amp;lt;!-- marks the end of the package phase --&amp;gt;&lt;br /&gt; &amp;lt;target name="package.done" depends="package.jar,package.copy.dependencies"/&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-1112081557146118085?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/1112081557146118085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=1112081557146118085' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1112081557146118085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/1112081557146118085'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/09/using-maven-ant-tasks-instead-of-ivy.html' title='Using Maven-Ant-Tasks instead of Ivy.'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-4606446051939777947</id><published>2008-09-24T21:35:00.004-04:00</published><updated>2010-03-10T14:09:54.869-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='template'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><title type='text'>Masochism</title><content type='html'>&lt;span style="font-style:italic;"&gt;Note: Due to excessive comments about my grasp of the english languages, I've done a second round of editing for this post.  It may show up on the RSS feed again, but there isn't any new content.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've recently had to jump into a bit of (very minor) C++ development at work.  This started bringing back memories of all the ?fun? it was to play around in the C++ type system.  Mostly you use the C++ type system in an attempt to prevent yourself from doing bad things. Sometimes though, it was a way of doing conditional compilation in a type-safe manner.&lt;br /&gt;&lt;br /&gt;I recently decided to outline how I tend to over-engineer my C++ code.  I'll give a few ground rules/goals first:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; I won't use boost.  In real life, I do use boost whenever I can.  For the purposes of illustration I'm doing a lot by hand.  If you're a C++ developer and you don't use boost, go learn it. Now.  Really, I mean right now go to &lt;a href="http://www.boost.org"&gt;www.boost.org&lt;/a&gt; and enter the 21st century of coding.  No really, GO&lt;/li&gt;&lt;li&gt; I'm not doing detailed explanations (although I do some explanations) of the C++ language or its compiler workings.&lt;/li&gt;&lt;li&gt;This could be an attempt to ramp myself to attack learning scala's (and maybe haskell's) type sytem.  C++ is the closest typed language I know that could prepare me&lt;/li&gt;&lt;li&gt;C++/Java feels more like massochism the more new languages I learn.  I'm hoping this "simple" post about using the C++ type system in a "simple" way will prove this to you.  At some point I hope to post a Scala/Haskell equivalent to this post (or perhaps someone else would like to?) just so you can see the amount of work C++ really requires (and the level of understanding required to write even a simple line).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Alright! so first off, the premise:  &lt;b&gt;We're trying to create a class (DynamicLibrary) that will let us dynamic load a shared library and access symbols.&lt;/b&gt;  I'm only including code for linux (although porting to windows or "cross-platforming" isn't too bad. look into the LoadLibrary function in windows and dlopen in linux).&lt;br /&gt;&lt;br /&gt;Before we begin, I'm going to construct something (available in boost) that should be in the utility kit of every C++ developer... a base class that removes the copy-constructor and operator= from visibility (effectively making it non-copyable)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: cpp"&gt;#ifndef NONCOPYABLE_H_&lt;br /&gt;#define NONCOPYABLE_H_&lt;br /&gt;//============================================================================&lt;br /&gt;// This class prevents copying on subclasses&lt;br /&gt;//============================================================================&lt;br /&gt;template&lt;class T&gt;&lt;br /&gt;class NonCopyable&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;inline NonCopyable() {}&lt;br /&gt;inline ~NonCopyable() {}&lt;br /&gt;private:&lt;br /&gt;NonCopyable(NonCopyable&amp; other) {}&lt;br /&gt;NonCopyable&amp; operator=(NonCopyable&amp; other) {}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#endif&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's a very simple class.  Most of its functions are purposefully inlined.  It should get compiled out during optimization phases, AND it can reduce typing for me later when I don't want a class copied around on the stack.&lt;br /&gt;(Note: I could have saved one line of typing by changing to a struct and getting rid of the public: line. or putting all private functions first.  Sue me, but I prefer this look).&lt;br /&gt;&lt;br /&gt;Ok, next we're going to create a very small Meta-Programming Library.  This library will be used to tell us all sorts of information about the types in C++.  For now, please assume all these examples are surrounded in a namespace mpl {} block.&lt;br /&gt;&lt;br /&gt;Here's our first bout of magic:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;struct true_;&lt;br /&gt;struct false_;  //Not really needed, but easier to understand if we have it&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;WTF? Why make two completely silly classes?  This is so I can represent the notion of a boolean in the type system. From now on, I want you to think of true_ as "true in the meta-programming library" and similarly for false_. &lt;i&gt;Note: In actuality I could probably use bool as a template parameter and get away with it, but this is more fun&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ok, now let's make a simple method just so we can print the boolean value of a type.  &lt;br /&gt;&lt;pre class="brush: cpp"&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;struct is_true&lt;br /&gt;{&lt;br /&gt;enum { value = 0 };&lt;br /&gt;};&lt;br /&gt;template&amp;lt:&amp;gt;&lt;br /&gt;struct is_true&amp;lt;true_&amp;gt;&lt;br /&gt;{&lt;br /&gt;enum { value = 1 };&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So..... what is that?   That, my friends, is a C++ meta-programming function.  The first template applies to every type and "returns" a value of 0 (or false).  The second is a specialization for the true_ type that will return 1.  This means if we ever use the is_true structure with true_ as the argument, the "member" value will be 1.  Its a little convoluted (or convolved?), but it works!  How do you call it?  Simply like this:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;is_true&amp;lt;some type&amp;gt;::value.&lt;/pre&gt;&lt;br /&gt;That will return an actually value we can assign, test in an if statement or display on the console.  We're going for displaying on the console here (console = stdout).&lt;br /&gt;&lt;br /&gt;Ok, so let's get more interesting meta-functions.  The most important for what I'd like to do later is the "is_ptr" function.  Here's a look at it:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;struct is_ptr&lt;br /&gt;{&lt;br /&gt;typedef false_ value;&lt;br /&gt;};&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;struct is_ptr&amp;lt;T*&amp;gt;&lt;br /&gt;{&lt;br /&gt;typedef true_ value;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So before we saw "template specialization".  That is, template&lt;&gt; with all types completely specified in an alternative implementation of the function.  This time, we see "partial template specialization" (YAY!!?).  This is where we have an alternative implementation that still has some wildcards (i.e. partially specialized).  When used, the compiler will select the function from most specialized to most general based on our types, so we can get away with this.  &lt;br /&gt;&lt;br /&gt;Now, what's that funny type-def doing and why isn't "value" part of an enum?  Well this meta-function takes a type as argument and returns a type (not a value).  You can string together meta-functions of this kind to make even stranger (and horrendous to look at) meta-functions.&lt;br /&gt;&lt;br /&gt;As a simple example, let's make an "if" meta-function:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;template&amp;lt;typename COND, typename T, typename F&amp;gt;&lt;br /&gt;struct if_&lt;br /&gt;{&lt;br /&gt;typedef F value;&lt;br /&gt;};&lt;br /&gt;template&amp;lt;typename T, typename F&amp;gt;&lt;br /&gt;struct if_&amp;lt;true_, T, F&amp;gt;&lt;br /&gt;{&lt;br /&gt;typedef T value;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The above is a structure that will select either type T or F based on the valiue of COND (much like an if statement).&lt;br /&gt;&lt;br /&gt;For now, let's test our first two meta-functions on a few combinations of the various incarnations of ints in C++.&lt;br /&gt;&lt;pre class="brush: cpp"&gt;cout &amp;lt;&amp;lt; "mpl::is_ptr&amp;lt;int*&amp;gt;::value = " &amp;lt;&amp;lt; mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;int*&amp;gt;::value&amp;gt;::value &amp;lt;&amp;lt; endl;&lt;br /&gt;cout &amp;lt;&amp;lt; "mpl::is_ptr&amp;lt;int&amp;gt;::value = " &amp;lt;&amp;lt; mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;int&amp;gt;::value&amp;gt;::value &amp;lt;&amp;lt; endl;&lt;br /&gt;cout &amp;lt;&amp;lt; "mpl::is_ptr&amp;lt;const int&amp;gt;::value = " &amp;lt;&amp;lt; mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;const int&amp;gt;::value&amp;gt;::value &amp;lt;&amp;lt; endl;&lt;br /&gt;cout &amp;lt;&amp;lt; "mpl::is_ptr&amp;lt;const int*&amp;gt;::value = " &amp;lt;&amp;lt; mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;const int*&amp;gt;::value&amp;gt;::value &amp;lt;&amp;lt; endl;&lt;br /&gt;cout &amp;lt;&amp;lt; "mpl::is_ptr&amp;lt;volatile int&amp;gt;::value = " &amp;lt;&amp;lt; mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;volatile int&amp;gt;::value&amp;gt;::value &amp;lt;&amp;lt; endl;&lt;br /&gt;cout &amp;lt;&amp;lt; "mpl::is_ptr&amp;lt;const volatile int&amp;gt;::value = " &amp;lt;&amp;lt; mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;const volatile int&amp;gt;::value&amp;gt;::value &amp;lt;&amp;lt; endl;&lt;br /&gt;cout &amp;lt;&amp;lt; "mpl::is_ptr&amp;lt;volatile int*&amp;gt;::value = " &amp;lt;&amp;lt; mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;volatile int*&amp;gt;::value&amp;gt;::value &amp;lt;&amp;lt; endl;&lt;br /&gt;cout &amp;lt;&amp;lt; "mpl::is_ptr&amp;lt;const volatile int*&amp;gt;::value = " &amp;lt;&amp;lt; mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;const volatile int*&amp;gt;::value&amp;gt;::value &amp;lt;&amp;lt; endl;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And the output is: &lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre&gt;mpl::is_ptr&amp;lt;int*&amp;gt;::value = 1&lt;br /&gt;mpl::is_ptr&amp;lt;int&amp;gt;::value = 0&lt;br /&gt;mpl::is_ptr&amp;lt;const int&amp;gt;::value = 0&lt;br /&gt;mpl::is_ptr&amp;lt;const int*&amp;gt;::value = 1&lt;br /&gt;mpl::is_ptr&amp;lt;volatile int&amp;gt;::value = 0&lt;br /&gt;mpl::is_ptr&amp;lt;const volatile int&amp;gt;::value = 0&lt;br /&gt;mpl::is_ptr&amp;lt;volatile int*&amp;gt;::value = 1&lt;br /&gt;mpl::is_ptr&amp;lt;const volatile int*&amp;gt;::value = 1&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Neat-o huh?  Yeah I probably could change the output to really represent things, ie mpl::is_true&amp;lt;mpl::is_ptr&amp;lt;....&amp;gt;::value&amp;gt;::value ? "true_" : "false_".  However it was already way to much typing.&lt;br /&gt;&lt;br /&gt;Ok, now onto why we were making meta-functions to begin with.  I want a somewhat type-safe way of importing symbols from a dynamicly loaded library and casting them to their appropriate types. This idea came from an old colleague at APL.  I hope this solution is different enough, as I don't recall his solution.  &lt;br /&gt;&lt;br /&gt;Let's start off with our basic class structure for DynamicLib:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;//ASSUME LIBRARY_HANDLE_TYPE and SYMBOL_POINTER_TYPE are defined somewhere above (os-specific)&lt;br /&gt;class DynamicLib : public NonCopyable&amp;lt;DynamicLib&amp;gt; {&lt;br /&gt;public:&lt;br /&gt;DynamicLib(const char*const name); //implementation is OS-specific&lt;br /&gt;~DynamicLib();                     //implementation is os-specific&lt;br /&gt;static SYMBOL_POINTER_TYPE get_symbol_internal(const char*const name, LIBRARY_HANDLE_TYPE handle); //implementation is OS-specific.  Didn't feel like figuring out to privatize this.&lt;br /&gt;private:&lt;br /&gt;LIBRARY_HANDLE_TYPE handle; //handle to library (os-specific)&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;First off, notice the use of NonCopyable.  This ensures the class cannot be copied (i.e. you have to use pointers to share it).  This helps us ensure that the library is loaded once and destroyed once.  You could still construct it twice for the same library, but if you do that... well a maniacal penguin dressed in a business suit will come steal your fish.&lt;br /&gt;&lt;br /&gt;Next, the get_symbol_internal method is static.  This is because the public (local) method has yet to be written and needs to use the MPL library (YAY!!!?).  What we'd like to do is find a way to return primitives by value, and everything else by pointer.  I'm going to call anything a "primitive" if it has a valid copy constructor (boy would this be wrong in a large app).  Instead of pulling in &lt;a href="http://stlsoft.com"&gt;Matthew Wilson&lt;/a&gt;'s &lt;a href="http://www.synesis.com.au/software/stlsoft/doc-1.9/unionstlsoft_1_1must__be__pod.html"&gt;"must_be_pod"&lt;/a&gt; meta-function-constraint, I think I'll just assume proper usage (like a fool).  &lt;span style="font-style:italic;"&gt;Note: A maniacal penguin did show up at my door, but I was able to dissuade it with a tennis racket and tuna fish.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ok, so onto the symbol loading...  Here's what our public symbol loading function looks like:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;//function for external use&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;inline T get_symbol(const char*const name) {&lt;br /&gt;//Call appropriate function based on whether type is pointer or not.&lt;br /&gt;typedef get_symbol_&amp;lt;T, typename mpl::is_ptr&amp;lt;T&amp;gt;::value&amp;gt; get_symbol_functor;&lt;br /&gt;get_symbol_functor functor; //need an instance to use operator()...&lt;br /&gt;return functor(name, handle);&lt;br /&gt;}&lt;br /&gt;private:&lt;br /&gt;template&amp;lt;typename T, typename isptr&amp;gt;&lt;br /&gt;struct get_symbol_;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Well, that's simple.  Too bad it won't compile when someone actually tries to use it.  What's going on here?  Well the get symbol function is templatized on some type.  Then we try to call the get_symbol_ &lt;b&gt;functor struct&lt;/b&gt;.  What is a functor struct (besides a lame excuse for a closure/real functor)?  It's a structure that (sort of) looks like a function in code (as shown above).   We declare (but not define) the structure.  The structure is where we will specialize our implementation for pointer types vs. non-ptr types.  Since we're using the "is_ptr" meta function above, all we need are two partial specialization for the get_symbol_ functor.  The first specialization will take "true_" as its second type parameter. The second specialization will take "false_" as its second type parameter.  The false variant should perform a copy of the value pointed at by the symbol.  The true variant can just cast and return the symbol pointer.  Here's the code:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;//Repeated for clarity&lt;br /&gt;template&amp;lt;typename T, typename isptr&amp;gt;&lt;br /&gt;struct get_symbol_;&lt;br /&gt;&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;struct get_symbol_&amp;lt;T, typename mpl::true_&amp;gt; {&lt;br /&gt;T operator()(const char*const name, void* handle) {&lt;br /&gt;//This should fail to compile for types that don't have copy-constructors&lt;br /&gt;return reinterpret_cast&amp;lt;T&amp;gt;(DynamicLib::get_symbol_internal(name, handle));&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;//Get symbol for non-ptr types&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;struct get_symbol_&amp;lt;T, typename mpl::false_&amp;gt; {&lt;br /&gt;T operator()(const char*const name, void* handle) {&lt;br /&gt;//TODO - Fix const...&lt;br /&gt;return *static_cast&amp;lt;T*&amp;gt;(DynamicLib::get_symbol_internal(name, handle));&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now you can see how a struct-functor is created.  Basically you just define an operator() overload inside the structure, and it will start acting like a function (or at least looking like one...).&lt;br /&gt;&lt;br /&gt;You can see how on the one hand we're de-referencing the pointer, and on the other we're just casting.  I'm also going to assume here (wrongly) that the get_symbol_internal will throw an exception on error, thereby ensuring that I will never dereference an invalid pointer (feel free to laugh, or send the penguin again).&lt;br /&gt;&lt;br /&gt;Ok, and now for the main method that uses this mess of code (note I'm using getopt.h):&lt;br /&gt;&lt;pre class="brush: cpp"&gt;int main(int argc, char*argv[]) {&lt;br /&gt;int c;&lt;br /&gt;extern char* optarg;&lt;br /&gt;extern int optind, optopt;&lt;br /&gt;string library = "";&lt;br /&gt;string symbol = "";&lt;br /&gt;string type = "";&lt;br /&gt;bool usage = false;&lt;br /&gt;while ((c = getopt(argc, argv, "l:s:t:h")) != -1) {&lt;br /&gt;switch (c) {&lt;br /&gt;case 'l':&lt;br /&gt;library = optarg;&lt;br /&gt;break;&lt;br /&gt;case 's':&lt;br /&gt;symbol = optarg;&lt;br /&gt;break;&lt;br /&gt;case 't':&lt;br /&gt;type = optarg;&lt;br /&gt;break;&lt;br /&gt;case '?':&lt;br /&gt;cerr &amp;lt;&amp;lt; "Unrecognized option: -" &amp;lt;&amp;lt; static_cast&amp;lt;char&amp;gt; (optopt)&lt;br /&gt;&amp;lt;&amp;lt; endl;&lt;br /&gt;case 'h':&lt;br /&gt;usage = true;&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (usage) {&lt;br /&gt;//TODO&lt;br /&gt;return 2;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;DynamicLib lib(library.c_str());&lt;br /&gt;&lt;br /&gt;if(type == "int") {&lt;br /&gt;cerr &amp;lt;&amp;lt; "Symbol value (as int) is: " &amp;lt;&amp;lt; lib.get_symbol&amp;lt;int&amp;gt; (symbol.c_str()) &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;if(type == "function") {&lt;br /&gt;cerr &amp;lt;&amp;lt; "Symbol value (as return of function [int ()] ) is: " &amp;lt;&amp;lt; lib.get_symbol&amp;lt;int (*)()&amp;gt; (symbol.c_str())() &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The hardest one to understand here is possibly the function pointer.  Basically I'm asking for a pointer to a no-argument function that returns an integer [int (*)()].  I then immediately call this function for a value to place in cerr.&lt;br /&gt;&lt;br /&gt;Ok, now we need a shared-library to test out.  Here's my dummy .cpp that I compiled into a .so (I leave that as an excersie to the user).&lt;br /&gt;&lt;pre class="brush: cpp"&gt;extern "C" {&lt;br /&gt;int MY_VAL = 5;&lt;br /&gt;int MY_FUNC() { return MY_VAL; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Onto our outputs:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre&gt;&gt;  Debug/cpp-types -l ../dummy-shared-lib/Debug/libdummy-shared-lib.so -s MY_VAL -t int&lt;br /&gt;Symbol value (as int) is: 5&lt;br /&gt;&gt;  Debug/cpp-types -l ../dummy-shared-lib/Debug/libdummy-shared-lib.so -s MY_FUNC -t function&lt;br /&gt;Symbol value (as return of function [int ()] ) is: 5&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Ok, so this is a little bit limited, but we have it working! YAY!!!?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In conclusion, I really want to get back into Scala again.  The type system seems a little bit less verbose, and the language itself is less clunky.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Note: I later updated this to pull string-literals out of libraries.  The fun part there was realizing that a symbol pointer to  a string literal is *really* a [char**] that needs to be dereferenced (carefully).  Basically I wrote a specialized std::string specialization of get_symbol that would perform the checks/casts and return a string.  The key to testing this was ensuring that the char* literal would wind up in the symbol table of the output .so.  This means you should make a dummy function that returns it, otherwise it may be optimized away.  Enjoy!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-4606446051939777947?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/4606446051939777947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=4606446051939777947' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/4606446051939777947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/4606446051939777947'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/09/massochism.html' title='Masochism'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-3757254985721456534</id><published>2008-09-23T17:58:00.000-04:00</published><updated>2008-09-23T18:07:16.724-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ajp'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='proxy'/><title type='text'>Reader Response: proxy_ajp is better than mod_jk</title><content type='html'>&lt;span style="font-style:italic;"&gt;Wow, so not only do I have readers, but I have readers willing to contribute their time to improving the information available on this blog!   Special thanks to Emerson for this post.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is a complementary post to Ubuntu Dev Server - Hudson&lt;a href="#one"&gt;[1]&lt;/a&gt; with a simpler way (IMO) to integrate Tomcat with Apache.&lt;br /&gt;&lt;br /&gt;This can be achieved by enabling mod_proxy and mod_proxy_ajp in Apache. If you also use ubuntu-server, like I do, just link them symbolically:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;$ sudo ln -s /etc/apache2/mods-available/mod_proxy /etc/apache2/mods-enabled/mod_proxy&lt;br /&gt;$ sudo ln -s /etc/apache2/mods-available/mod_proxy_ajp /etc/apache2/mods-enabled/mod_proxy_ajp&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now edit apache2.conf like this: &lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&amp;lt;Location /your_tomcat_app&amp;gt;&lt;br /&gt;ProxyPass ajp://your_host:8009/your_tomcat_app&lt;br /&gt;Order allow,deny&lt;br /&gt;allow from all&lt;br /&gt;&amp;lt;/Location&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Then restart Apache and it's done. To add another application, just repeat the same setup above mutatis mutandis&lt;a href="#two"&gt;[2]&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One additional setup for my application was to enable access to URLs, like &amp;lt;http://my-server/my-tomcat-app/servlet/my-servlet-name&amp;gt;. To do this, edit /etc/tomcat5.5/web.xml and find the string "invoker". You will find the following commented servlet element:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&amp;lt;!--&lt;br /&gt;   &amp;lt;servlet&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&gt;invoker&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;servlet-class&amp;gt;&lt;br /&gt;          org.apache.catalina.servlets.InvokerServlet&lt;br /&gt;        &amp;lt;/servlet-class&amp;gt;&lt;br /&gt;        &amp;lt;init-param&amp;gt;&lt;br /&gt;            &amp;lt;param-name&gt;debug&amp;lt;/param-name&amp;gt;&lt;br /&gt;            &amp;lt;param-value&gt;0&amp;lt;/param-value&amp;gt;&lt;br /&gt;        &amp;lt;/init-param&amp;gt;&lt;br /&gt;        &amp;lt;load-on-startup&gt;2&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Just strip the comment tags and restart Tomcat. Integrating Tomcat with Apache should be that easy since the beginning.&lt;br /&gt;&lt;br /&gt;&lt;a name="one"&gt;&lt;/a&gt;[1] &lt;a href="http://suereth.blogspot.com/2008/08/ubuntu-dev-server-hudson.html"&gt;http://suereth.blogspot.com/2008/08/ubuntu-dev-server-hudson.html&lt;/a&gt;&lt;br /&gt;&lt;a name="two"&gt;&lt;/a&gt;[2] &lt;a href="http://en.wikipedia.org/wiki/Mutatis_mutandis"&gt;http://en.wikipedia.org/wiki/Mutatis_mutandis&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-3757254985721456534?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/3757254985721456534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=3757254985721456534' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/3757254985721456534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/3757254985721456534'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/09/reader-response-proxyajp-is-better-than.html' title='Reader Response: proxy_ajp is better than mod_jk'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-5925665310073295065</id><published>2008-09-17T14:05:00.000-04:00</published><updated>2008-09-17T22:08:12.993-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='winstone'/><category scheme='http://www.blogger.com/atom/ns#' term='ajp'/><category scheme='http://www.blogger.com/atom/ns#' term='hudson'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Hudson on Winstone + Apache</title><content type='html'>I decided to make a quick post about hudson.  I've been using it for work for a few weeks now and after the initial setup it's required almost no maintenance.  I also like how easier it is to extend and setup.&lt;br /&gt;&lt;br /&gt;Anyway, just thought I'd include some screenshots of installing plugins for hudson.  It's as simple as clicking through the web interface and then restarting the server.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_zY6AYwdFmgA/SNG3KX89m9I/AAAAAAAAABQ/rs74AqlZon4/s1600-h/hudson+available+plugins.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_zY6AYwdFmgA/SNG3KX89m9I/AAAAAAAAABQ/rs74AqlZon4/s320/hudson+available+plugins.PNG" alt="" id="BLOGGER_PHOTO_ID_5247176429719624658" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And here's downloading a plugin:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_zY6AYwdFmgA/SNG3b9oNDRI/AAAAAAAAABY/hmn67JMTZXA/s1600-h/hudson+downloading+plugins.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_zY6AYwdFmgA/SNG3b9oNDRI/AAAAAAAAABY/hmn67JMTZXA/s320/hudson+downloading+plugins.PNG" alt="" id="BLOGGER_PHOTO_ID_5247176731890879762" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;War Games?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hudson has the neat ability to run only using the war.  It makes use of a servlet container called "winstone".  This was my first look into winstone, but one of the nice features (that tomcat also has) is AJP support.  Let's look at how we can install hudson as a service (I'm using CentOS 5.2 for this).&lt;br /&gt;&lt;br /&gt;First, create a hudson user and group.  Next create a /var/hudson directory.  Make sure hudson owns this directory.  Place the hudson.war into it.&lt;br /&gt;&lt;br /&gt;Here's an init script I modified from the &lt;a href="http://hudson.gotdns.com/wiki/display/HUDSON/Installation+and+Execution"&gt;comments on Hudson's install instructions&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;# chkconfig: 2345 84 16&lt;br /&gt;# description: Hudson CI server&lt;br /&gt;&lt;br /&gt;# Source function library.&lt;br /&gt;. /etc/rc.d/init.d/functions&lt;br /&gt;[ -z "$JAVA_HOME" -a -x /etc/profile.d/java.sh ] &amp;amp;&amp;amp; . /etc/profile.d/java.sh&lt;br /&gt;&lt;br /&gt;USER=hudson&lt;br /&gt;HUDSON_HOME=/var/hudson&lt;br /&gt;WAR="$HUDSON_HOME/hudson.war"&lt;br /&gt;LOG="/var/log/hudson.log"&lt;br /&gt;LOCK="/var/lock/subsys/hudson"&lt;br /&gt;export HUDSON_HOME&lt;br /&gt;&lt;br /&gt;RETVAL=0&lt;br /&gt;&lt;br /&gt;pid_of_hudson() {&lt;br /&gt;  ps auxwww | grep java | grep hudson | grep -v grep | awk '{print $2}'&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;start() {&lt;br /&gt;  [ -e "$LOG" ] &amp;amp;&amp;amp; cnt=`wc -l "$LOG" | awk '{ print $1 }'` || cnt=1&lt;br /&gt;&lt;br /&gt;  echo -n $"Starting hudson: "&lt;br /&gt;&lt;br /&gt;  echo "" &amp;gt; "$LOG"&lt;br /&gt;  chown $USER $LOG&lt;br /&gt;  cd "$HUDSON_HOME"&lt;br /&gt;&lt;br /&gt;  CMD="nohup ${JAVA_HOME}/bin/java -DHUDSON_HOME=${HUDSON_HOME} -jar ${WAR} --httpPort=8080 --ajp13Port=8010 --prefix=/hudson &amp;gt;&amp;gt; ${LOG} 2&amp;gt;&amp;amp;1 &amp;amp;"&lt;br /&gt;  su -m --command="${CMD}" hudson&lt;br /&gt;  while { pid_of_hudson &amp;gt; /dev/null ; } &amp;amp;&amp;amp;&lt;br /&gt;        ! { cat "$LOG" | grep -q 'Winstone Servlet Engine .* running' ; } ; do&lt;br /&gt;      sleep 1&lt;br /&gt;  done&lt;br /&gt;&lt;br /&gt;  pid_of_hudson &amp;gt; /dev/null&lt;br /&gt;  RETVAL=$?&lt;br /&gt;  [ $RETVAL = 0 ] &amp;amp;&amp;amp; success $"$STRING" || failure $"$STRING"&lt;br /&gt;  echo&lt;br /&gt;&lt;br /&gt;  [ $RETVAL = 0 ] &amp;amp;&amp;amp; touch "$LOCK"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;stop() {&lt;br /&gt;  echo -n "Stopping hudson: "&lt;br /&gt;&lt;br /&gt;  pid=`pid_of_hudson`&lt;br /&gt;  [ -n "$pid" ] &amp;amp;&amp;amp; kill $pid&lt;br /&gt;  RETVAL=$?&lt;br /&gt;  cnt=10    while [ $RETVAL = 0 -a $cnt -gt 0 ] &amp;amp;&amp;amp;&lt;br /&gt;        { pid_of_hudson &gt; /dev/null ; } ; do&lt;br /&gt;      sleep 1&lt;br /&gt;      ((cnt--))&lt;br /&gt;  done&lt;br /&gt;&lt;br /&gt;  [ $RETVAL = 0 ] &amp;amp;&amp;amp; rm -f "$LOCK"&lt;br /&gt;  [ $RETVAL = 0 ] &amp;amp;&amp;amp; success $"$STRING" || failure $"$STRING"&lt;br /&gt;  echo&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;status() {&lt;br /&gt;  pid=`pid_of_hudson`&lt;br /&gt;  if [ -n "$pid" ]; then&lt;br /&gt;      echo "hudson (pid $pid) is running..."&lt;br /&gt;      return 0&lt;br /&gt;  fi&lt;br /&gt;  if [ -f "$LOCK" ]; then&lt;br /&gt;      echo $"${base} dead but subsys locked"&lt;br /&gt;      return 2&lt;br /&gt;  fi&lt;br /&gt;  echo "hudson is stopped"&lt;br /&gt;  return 3&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# See how we were called.&lt;br /&gt;case "$1" in&lt;br /&gt;start)&lt;br /&gt;  start&lt;br /&gt;  ;;&lt;br /&gt;stop)&lt;br /&gt;  stop&lt;br /&gt;  ;;&lt;br /&gt;restart)&lt;br /&gt;  stop&lt;br /&gt;  start&lt;br /&gt;  ;;&lt;br /&gt;*)&lt;br /&gt;  echo $"Usage: $0 {start|stop|restart|status}"&lt;br /&gt;  exit 1&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;exit $RETVAL&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After creating the file, make sure you install it with &lt;div class="sourceCode"&gt;chkconfig --add hudson&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Finally, if we only want to open port 80, it's easy to configure apache to forward to winstone using mod_ajp.   Here's my apache configuration:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;LoadModule proxy_ajp_module modules/mod_proxy_ajp.so&lt;br /&gt;ProxyPass /hudson/ ajp://localhost:8010/hudson/&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now just head to http://localhost/hudson and you should see hudson.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-5925665310073295065?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/5925665310073295065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=5925665310073295065' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5925665310073295065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/5925665310073295065'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/09/hudson-on-winstone-apache.html' title='Hudson on Winstone + Apache'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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://2.bp.blogspot.com/_zY6AYwdFmgA/SNG3KX89m9I/AAAAAAAAABQ/rs74AqlZon4/s72-c/hudson+available+plugins.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-4348937246023340003</id><published>2008-08-26T22:06:00.000-04:00</published><updated>2008-08-26T22:31:27.310-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='archiva'/><category scheme='http://www.blogger.com/atom/ns#' term='hudson'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Entirely Too Motivated</title><content type='html'>So this week I've been very motivated to work on my more nerdy hobbies.  Here's an update on my latest progress&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Made use of Hudson to set up a continuous build.  WOW is this software great.  I'm amazed at how good free software can get!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Attempted to get a Scala job up on hudson, so I'll know early on when scala fails on windows.  :Sigh:  I'm not sure what's going on here, but it looks like no one at EPFL really wants to maintain Scala for windows.  While I understand their sentiments, I now have a mini-project at work that I cannot develop for because they've broken the eclipse plugin.  I've managed to compile with an older scala, but this means I've lost my dev environment.  I've heard someone say, if you stay on the bleeding-edge, expect to bleed.  I guess I was hoping scala was further along in maturity then this.  Oh well, back to contributing bug-fixes/enhancements in my spare time and secretly hoping we can use this for future development.&lt;br /&gt;&lt;li&gt;I managed to get Archiva up and running on ubuntu.  For some reason (probably my stupidity), I had a difficult time figuring out where the common/lib file was.  (Archiva requires derby, mail and activation in common/lib).  For those of you like myself, common/lib is under /usr/share/tomcat5.5 NOT /var/lib/tomcat5.5.  Anyway, now that I have archiva + hudson + trac up and running, it's time for a really sweet development environment.  I'm working on trying to wire at least hudson into our project at work.  I'll probably be posting what's useful and what to avoid later.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Also I'd like to take this time for a mini-rant.  &lt;br /&gt;&amp;lt;rant&amp;gt;&lt;br /&gt;I'm really confused here.  I got on the #eclipse-dev list serve to ask some questions about the eclipse PDE project.  I received answers on where to look to solve my issues.  I got on the #scala list serve to ask some general architecture questions, and was told to look at some haskell apps because Scala is impure (Note: this is my wording).  Ok, the haskel App engine thing looked pretty cool, but I couldn't get past the syntax...(I'd rather read LOLCode all day).  How many key contributors to Scala feel it's a "less-good" Haskell?  I know a lot of libraries are inspired by Haskell, but not a lot of libraries appear to be inspired from other JVM languages.  This confuses me, as I thought Scala was targeted towards Java developers.  There aren't a lot of Helper routines to make using Scala with existing java code/libraries easier.&lt;br /&gt;&lt;br /&gt;Example:  I'm integrating with a bunch of Java-Threaded code.  It uses Runnable and callable.  I created a JavaThreadConversion object that looks like this:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;object JavaThreadConversion&lt;br /&gt;{&lt;br /&gt;  def functionToRunnable(f : =&gt; Unit) = new Runnable() {&lt;br /&gt;     override def run() = f&lt;br /&gt;  }&lt;br /&gt;  import java.util.conncurrent.Callable&lt;br /&gt;  def functionToCallable[A](f : =&gt; A) = new Callable() {&lt;br /&gt;     override def call() = f&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That little bit of code save me a lot of typing when interfacing with my old java libraries.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Why don't you rewrite them in scala&lt;/i&gt;   Not enough time/money/priority.  Not gonna happen any time soon.&lt;br /&gt;&lt;br /&gt;Oh well.  Hopefully as more Java developers see the power of scala, they'll begin to contribute more utilities that can make transitioning off java easier.  Until then, I'll see what of mine really is useful and can pass the "functional purity" filter.&lt;br /&gt;&lt;br /&gt;Amusing note: At point I wondered why there weren't any Scala + OSGi helpers as I hear a lot of people asking how to do XYZ scala task using OSGi.  I'd like to see how much that make a FP purist cringe... OSGi seems to be the bane of FP.  Even worse would be the mixing of a Scala core with a Groovy plugin system...&lt;br /&gt;&amp;lt;/rant&amp;gt;&lt;br /&gt;&lt;br /&gt;Anyway, don't mean to offend anyone.  Just frustrated with certain things, including my slow-learning-process for various FP concepts (like monads)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-4348937246023340003?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/4348937246023340003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=4348937246023340003' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/4348937246023340003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/4348937246023340003'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/08/entirely-too-motivated.html' title='Entirely Too Motivated'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1673113361032868171.post-6423995013418857421</id><published>2008-08-25T20:24:00.001-04:00</published><updated>2008-08-25T22:50:10.923-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='curried functions'/><category scheme='http://www.blogger.com/atom/ns#' term='duck-typing'/><category scheme='http://www.blogger.com/atom/ns#' term='loan pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Statically Duck-Typed (Take 2)</title><content type='html'>So I've been reading the "Programming in Scala" book in my spare time.  There's a lot of neat patterns to learn from the Scala language.  Anyway, I was reading about curried functions and the loan pattern, and decided to write an updated version of my "doThenClose" helper method.&lt;br /&gt;&lt;br /&gt;To accomplish this, we want to change the "doThenClose" method (which was on a "RichCloseable" object).  Here's what we need to do:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Rename to "withResource"&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make doThenClose global&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make it take in a "resource" or "closeable"&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Modify the type parameters so we don't lose the original type of the closeable.  (This way we can "loan" it to the function that uses it&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Modify the type of functions we take to those that operate on the type based in and return something&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Here's our original "doThenClose" method &lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;/**&lt;br /&gt;   * Defines new scala-awesome features we want.&lt;br /&gt;   */&lt;br /&gt;  class PimpedCloseable(closeable: MyCloseable) {&lt;br /&gt;     /**&lt;br /&gt;      * Executes a function, then closes the resource.&lt;br /&gt;      */&lt;br /&gt;     def doThenClose[A](f : =&gt; A) : Option[A]= {&lt;br /&gt;      try {&lt;br /&gt;        return Some(f)&lt;br /&gt;      } catch {&lt;br /&gt;      case _ =&gt; System.err.println("Trouble executing", f);&lt;br /&gt;      } finally {&lt;br /&gt;        CloseUtils.close(closeable);&lt;br /&gt;      }&lt;br /&gt;      return None;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And here's the new version:&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;  def withResource[A &lt;: Closeable, B](closeable : A)( f : A =&gt; B) = {&lt;br /&gt;    try {&lt;br /&gt;      f(closeable)&lt;br /&gt;    } finally {&lt;br /&gt;      CloseUtils close closeable&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;First of, let's describe the type parameters.  "A &lt;: Closeable" means "anything meeting the closeable interface"  and "B" is the return type of the withResource method (which we infer from the argument that will use our resource).  Also remember that Closeable is a TYPE not a class (i.e. type Closeable = { def close() : Unit } ).  This is where the "static duck-typing" comes in.&lt;br /&gt;&lt;br /&gt;Now, the method (withResource) defines what appears to be &lt;b&gt;two&lt;/b&gt; argument lists.  What this is really doing is creating two functions, the first generates the second.  This is the function currying.  The result of this, is that when calling the function, you use two argument lists as well.  Because scala performs some syntactic sugar for 1-argument functions, we can use {} instead of () to surround either of the arguments.  What this means is we can write the following test application:&lt;br /&gt;&lt;br /&gt;&lt;div class="sourceCode"&gt;&lt;pre class="prettyprint"&gt;object BlogTest {&lt;br /&gt;  def main(args : Array[String]) : Unit = {&lt;br /&gt;    import CloseUtils._&lt;br /&gt;    import java.io._&lt;br /&gt;    withResource(new FileInputStream("src/com/suereth/CloseUtils.scala")) {&lt;br /&gt;      file =&gt;&lt;br /&gt;       val reader = new BufferedReader(new InputStreamReader(file))&lt;br /&gt;       var line = reader.readLine()&lt;br /&gt;       while ( line != null ) {&lt;br /&gt;         System.out.println("" + line.trim.size + ":" + line)&lt;br /&gt;         line = reader.readLine&lt;br /&gt;       }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice the second argument list to "withResource" is { file =&gt; ...}.  This is a function that is "loaned" the resource created.  The function can do whatever it wants to the resource, however when it exists (via return or throw), the resource *will* be closed.  Although I'm not a fan of the "resource =&gt;" syntax, it's still a pretty amazing feature *and* totally user-defined.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1673113361032868171-6423995013418857421?l=suereth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://suereth.blogspot.com/feeds/6423995013418857421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1673113361032868171&amp;postID=6423995013418857421' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6423995013418857421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1673113361032868171/posts/default/6423995013418857421'/><link rel='alternate' type='text/html' href='http://suereth.blogspot.com/2008/08/statically-duck-typed-take-2.html' title='Statically Duck-Typed (Take 2)'/><author><name>J. Suereth</name><uri>http://www.blogger.com/profile/10176429810160937559</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-1673113361032868171.post-520525509738542283</id><published>2008-08-24T12:33:00.000-04:00</published><updated>2008-08-24T12:56:33.260-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='theme'/><category scheme='http://www.blogger.com/atom/ns#' term='slackware'/><category scheme='http://www.blogger.com/atom/ns#' term='trac'/><title type='text'>Trac Updates</title><content type='html'>A few updates on setting up your own Trac... &lt;br /&gt;&lt;br /&gt;First I finally got around to install plugins to Trac.  I've got graphviz, web admin, and a new theme.  Here's a few things that caught me up.&lt;br /&gt;&lt;br /&gt;First of all, I used easy_install (which I guess techinically isn't required.  You need to&lt;br /&gt;&lt;div class="sourceCode"&gt;sudo apt-get install python-setuptools&lt;/div&gt;  After which you can easily type:&lt;br /&gt;&lt;div class="sourceCode"&gt;sudo easy_install http://suversion-repo/for/trac/plugin&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I found a good theme manager here: &lt;a href="http://trac-hacks.org/"&gt;trac-hacks.org&lt;/a&gt; along with several themes that just improve the usage of trac.&lt;br /&gt;&lt;br /&gt;After installing a plugin you need to enable it like this in the trac.ini file for your project:&lt;br /&gt;&lt;div class="sourceCode"&gt;[components]&lt;br /&gt;  webadmin.* = enabled&lt;br /&gt;  graphviz.* = enabled&lt;br /&gt;&lt;/div&gt; (just keep adding the plugin name, .* = enabled)&lt;br /&gt;&lt;br /&gt;Each plugin may require other kinds of configuration.&lt;br /&gt;&lt;br /&gt;I'm also including an email I received from my friend John Sweeney.  John lists how to install Trac on slackware (yes, John could be a masochist).  Also, John's shows the apache configuration to enable basic logins and set up passwords.  THANKS AGAIN JOHN!  Here's the email:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Arial, sans-serif; margin-left: 1em;"&gt;&lt;br /&gt;Josh,&lt;br /&gt;&lt;br /&gt;I tried to post this i
