<?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-8515489</id><updated>2012-01-30T14:58:27.190-07:00</updated><category term='scala'/><category term='java'/><category term='constructors'/><category term='programming'/><category term='koan'/><title type='text'>logji</title><subtitle type='html'>noodling towards a functional brain</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://logji.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8515489.post-4449093711840942836</id><published>2011-08-17T15:04:00.001-06:00</published><updated>2011-08-17T15:04:51.790-06:00</updated><title type='text'>The magical Specs/ScalaCheck defaultPrettyParams configuration implicit</title><content type='html'>When using Specs with ScalaCheck, I have occasionally found myself annoyed that, when a function under test threw an exception, ScalaCheck didn't show me enough of a stack trace to actually figure out what was going on. There is a means to configure this, but to the best of my knowledge it's essentially not documented anywhere. In any case, to get full stack traces in your spec, all that you need is this:&lt;pre class="brush: scala"&gt;&lt;br /&gt;import org.specs._&lt;br /&gt;import org.scalacheck._&lt;br /&gt;&lt;br /&gt;class MySpec extends Specification with ScalaCheck {&lt;br /&gt;  override val defaultPrettyParams = Pretty.Params(2)&lt;br /&gt;&lt;br /&gt;  "your scalachecky specs here" should {&lt;br /&gt;     //...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The magical '2' in Pretty.Params(2) tells Scalacheck to spit out the full stack trace instead of just the error message from the exception.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-4449093711840942836?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/4449093711840942836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2011/08/magical-specsscalacheck.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/4449093711840942836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/4449093711840942836'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2011/08/magical-specsscalacheck.html' title='The magical Specs/ScalaCheck defaultPrettyParams configuration implicit'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-4404302014922217372</id><published>2011-02-27T09:17:00.002-07:00</published><updated>2011-02-28T17:50:40.046-07:00</updated><title type='text'>Code Retreat Boulder: Conway's Life</title><content type='html'>I had a ton of fun yesterday at Code Retreat Boulder, even though I ended up as the Scala guy and thus didn't get to play in other languages as much as I would have liked.Anyway, this morning I decided to recreate my favorite of the solutions. Small, simple, pure, and relatively flexible:&lt;pre class="brush: scala"&gt;&lt;br /&gt;import scala.annotation.tailrec&lt;br /&gt;&lt;br /&gt;trait Life {&lt;br /&gt;  type Entity&lt;br /&gt;  type Population = Set[Entity]&lt;br /&gt;&lt;br /&gt;  def generation(pop: Population) = pop.flatMap(neighborhood).filter {&lt;br /&gt;    entity =&gt; willLive(pop.contains(entity), neighbors(entity).count(pop.contains))&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def neighbors(entity: Entity): Seq[Entity]&lt;br /&gt;  def neighborhood(entity: Entity) = neighbors(entity) :+ entity&lt;br /&gt;&lt;br /&gt;  def willLive(now: Boolean, n: Int): Boolean&lt;br /&gt;  def render(pop: Population): Unit = println(pop)&lt;br /&gt;&lt;br /&gt;  @tailrec final def run(pop: Population): Unit = { &lt;br /&gt;    render(pop)&lt;br /&gt;    if (!pop.isEmpty) run(generation(pop))&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Life2D extends Life {&lt;br /&gt;  type Entity = (Int, Int)&lt;br /&gt;&lt;br /&gt;  override def willLive(now: Boolean, n: Int) = ((now &amp;&amp; n == 2) || n == 3)&lt;br /&gt;&lt;br /&gt;  override def neighbors(entity: Entity) = entity match {&lt;br /&gt;    case (x, y) =&gt; for (i &lt;- x-1 to x+1; j &lt;- y-1 to y+1 if !(i == x &amp;&amp; j == y)) yield (i, j)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object Blinker extends Life2D {&lt;br /&gt;  def main(argv: Array[String]) = run(Set((1, 0), (1, 1), (1, 2)))&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-4404302014922217372?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/4404302014922217372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2011/02/code-retreat-boulder-conways-life.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/4404302014922217372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/4404302014922217372'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2011/02/code-retreat-boulder-conways-life.html' title='Code Retreat Boulder: Conway&apos;s Life'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-1881469885307415459</id><published>2010-07-29T16:47:00.005-06:00</published><updated>2010-07-30T14:42:33.685-06:00</updated><title type='text'>A monad for failure-tolerant computations.</title><content type='html'>I was working on a problem today where some of the computations could fail, but degrade gracefully while providing information about how exactly they failed so that clients could choose whether or not to use the result. This is what I came up with:&lt;pre class="brush: scala"&gt;&lt;br /&gt;/**&lt;br /&gt; * A monad used to entrain computations on a value that might fail.&lt;br /&gt; * This is distinct from Either in that it allows computations to continue&lt;br /&gt; * in the presence of errors, with the possibility of a degraded result.&lt;br /&gt; * The user of the result can then decide its suitability for use based upon&lt;br /&gt; * any errors that might be returned. Errors must form a semigroup.&lt;br /&gt; */&lt;br /&gt;sealed trait Attempt[E, +A] {&lt;br /&gt;  def value: A&lt;br /&gt;  def map[B](f: A =&gt; B): Attempt[E, B]&lt;br /&gt;  def flatMap[B](f: A =&gt; Attempt[E, B]): Attempt[E, B]&lt;br /&gt;&lt;br /&gt;  def error: Option[E]&lt;br /&gt;  def either: Either[E, A]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case class Success[E, +A](value: A) extends Attempt[E, A] {&lt;br /&gt;  def map[B](f: A =&gt; B): Attempt[E, B] = Success(f(value))&lt;br /&gt;  def flatMap[B](f: A =&gt; Attempt[E, B]): Attempt[E, B] = f(value)&lt;br /&gt;  def error = None&lt;br /&gt;  def either = Right(value)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case class Failure[E, +A](err: E, value: A)(implicit append: (E, E) =&gt; E) extends Attempt[E, A] {&lt;br /&gt;  def map[B](f: A =&gt; B): Attempt[E, B] = Failure(err, f(value))&lt;br /&gt;  def flatMap[B](f: A =&gt; Attempt[E, B]): Attempt[E, B] = f(value) match {&lt;br /&gt;    case Failure(e, b) =&gt; Failure(append(e, err), b)&lt;br /&gt;    case Success(b)   =&gt; Failure(err, b)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def error = Some(err)&lt;br /&gt;  def either = Left(err)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Pretty trivial, but maybe occasionally useful. Here's how it looks in my code: &lt;pre class="brush: scala"&gt;&lt;br /&gt;  def mergeComponents(f: String =&gt; JSONReport): Attempt[List[String], JSONReport] = {&lt;br /&gt;    components.map(f).map(_.mergeComponents(f)).foldLeft[Attempt[List[String], JSONReport]](Success(this)) {&lt;br /&gt;      (result, comp) =&gt; for {&lt;br /&gt;        cur &lt;- result&lt;br /&gt;        jr  &lt;- comp&lt;br /&gt;        properties     &lt;- mergeProperties(cur, jr)&lt;br /&gt;        queries        &lt;- mergeQueries(cur, jr)&lt;br /&gt;        dataAliases    &lt;- mergeAliases(cur, jr, queries.values)&lt;br /&gt;        dataTransforms &lt;- mergeTransforms(cur, jr, dataAliases.values)&lt;br /&gt;        dataMailers    &lt;- mergeMailers(cur, jr, dataTransforms.values)&lt;br /&gt;      } yield {&lt;br /&gt;        JSONReport(&lt;br /&gt;          cur.reportId, cur.active, cur.version, properties,&lt;br /&gt;          queries, dataAliases, dataTransforms, dataMailers,&lt;br /&gt;          cur.dataRange, Nil&lt;br /&gt;        )&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Here each of the various mergeX methods return an Attempt[List[String], X] where X is something needed to build the ultimate report. Here I'm just aggregating lists of strings describing the errors, but of course any type for which (E, E) =&gt; E is defined would work.&lt;/p&gt;&lt;p&gt;Attempt. For all those times where you want a monad that says, "Hey, I maybe couldn't get exactly what you asked for. Maybe it's little broken, maybe it won't work right, but this the best I could do. You decide."&lt;/p&gt;&lt;b&gt;EDIT:&lt;/b&gt;&lt;p&gt;After a bit of thinking, I realized that this monad is really more general than being simply related to success or failure - it simply models a function that may or may not produce some additional metadata about its result. Then a lightbulb went off, and quick google search confirmed... yup, I just reinvented the &lt;a href="http://www.haskell.org/all_about_monads/html/writermonad.html"&gt;writer monad.&lt;/a&gt; It's not *exactly* like Writer, because it just requires a semigroup for E instead of a monoid, and the presence of a "log" is optional, so maybe it's better suited than Writer for a few instances.&lt;/p&gt;&lt;p&gt;The one really nice thing about rediscovering well-known concepts is that doing the derivation for yourself, in the context of some real problem, gives you a much more complete understanding of where the thing you reintevented is applicable!&lt;/p&gt;&lt;p&gt;Inspired by michid's example in the comments below, here's a simpler example that demonstrates some utility his doesn't quite capture.&lt;/p&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;implicit val append = (l1: List[String], l2: List[String]) =&gt; l1 ::: l2&lt;br /&gt;&lt;br /&gt;def succ(s: String) = Success[List[String], String]("result: success")&lt;br /&gt;val fail: String =&gt; Attempt[List[String], String] = { &lt;br /&gt;  var count = 0 &lt;br /&gt;  (s: String) =&gt; {&lt;br /&gt;    count += 1&lt;br /&gt;    Failure(List("failure " + count), s + " then failure")&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;val r = for {&lt;br /&gt;  x &lt;- succ("here we go!")&lt;br /&gt;  y &lt;- fail(x)&lt;br /&gt;  z &lt;- fail(y)&lt;br /&gt;} yield z&lt;br /&gt;&lt;br /&gt;println(r)&lt;br /&gt;&lt;/pre&gt;This results in: &lt;pre class="brush: scala"&gt;&lt;br /&gt;Failure(List(failure 2, failure 1),result: success then failure then failure)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-1881469885307415459?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/1881469885307415459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2010/07/monad-for-failure-tolerant-computations.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/1881469885307415459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/1881469885307415459'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2010/07/monad-for-failure-tolerant-computations.html' title='A monad for failure-tolerant computations.'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-5775313920589624357</id><published>2010-07-15T13:22:00.000-06:00</published><updated>2010-07-15T13:22:32.168-06:00</updated><title type='text'>An unfortunate situation.</title><content type='html'>&lt;p&gt;I've been working a bit with Hadoop lately. As many will know, there are essentially two versions of Hadoop that coexist within the Hadoop API; a deprecated legacy API and a newer one that is not nearly so feature-complete. It's a source of confusion to say the least.&lt;/p&gt;&lt;p&gt;Earlier today, I asked in the #hadoop channel on freenode, why were the breaking changes not simply made on a separate branch, the major version number incremented, and so forth such that everyone could move forward? The answers that I got back illuminated a troublesome trend that I think is worth considering for those projects (like my beloved Scala) that are moving towards professional support models of funding.&lt;/p&gt;&lt;p&gt;During the discussion, I commented that there is an unfortunate reality that the largest companies, who may provide the greatest support any given open-source project are also those who will likely be most conservative with respect to change. So as soon as open-source projects grow large enough that companies selling commercial support for those projects survive, there is an immediate disincentive for the support companies to make breaking changes. And stagnation ensues.&lt;/p&gt;&lt;p&gt;The response was startling. People who had been involved with numerous prominent businesses and projects immediately replied with stories of their own projects suffering such a fate, sometimes to the point that the project died entirely. &lt;/p&gt;&lt;p&gt;I think that this "success effect" can be traced to a single, simple cause, with a single, simple solution. Companies (and the individuals that make them up) need to stop thinking of mission-critical software as something that is ever complete. Marketing is never complete; sales is never done with their job, purchasing and HR are never done, nor is accounting. Software is no different - as engineers, we do not (and should not purport to) produce solutions to the problems that companies have; instead, we automate and support the operation of businesses so that businesses can do more, serve more customers, and in the end create more wealth. A project is finished when nobody is using it; never before then.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-5775313920589624357?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/5775313920589624357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2010/07/unfortunate-situation.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/5775313920589624357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/5775313920589624357'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2010/07/unfortunate-situation.html' title='An unfortunate situation.'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-180664142037494534</id><published>2010-02-05T14:35:00.002-07:00</published><updated>2010-02-05T14:43:32.460-07:00</updated><title type='text'>Trick of the day</title><content type='html'>James Iry just mentioned something I'd never noticed before in #scala:&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&amp;gt; def f(i: Int, x: Int) = i match { case `x` =&gt; println("x!"); case _ =&gt; println("nope") }&lt;br /&gt;f: (i: Int,x: Int)Unit&lt;br /&gt;&lt;br /&gt;scala&amp;gt; f(1, 1)&lt;br /&gt;x!&lt;br /&gt;&lt;br /&gt;scala&amp;gt; f(1, 2)&lt;br /&gt;nope&lt;br /&gt;&lt;/pre&gt;That's one of those things that I'd idly wondered how to do, but hadn't had a use case so hadn't really gone looking. Good to know it's possible and simple... and more or less makes sense.More or less. Actually, I guess I'm kind of glad that the following doesn't compile:&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&amp;gt; def f(i: Int) = i match { case `yield` =&gt; println(`yield`) }                           &lt;br /&gt;&amp;lt;console&amp;gt;:4: error: not found: value yield&lt;br /&gt;       def f(i: Int) = i match { case `yield` =&gt; println(`yield`) }&lt;br /&gt;&lt;/pre&gt;I can live with the restriction as not being able to use a reserved word for a variable on the lhs of a pattern match, though it does make for a weird inconsistency: &lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&amp;gt; val (`yield`, x) = (1, 1)&lt;br /&gt;&amp;lt;console&amp;gt;:4: error: not found: value yield&lt;br /&gt;       val (`yield`, x) = (1, 1)&lt;br /&gt;            ^&lt;br /&gt;&lt;br /&gt;scala&amp;gt; val `yield` = 1&lt;br /&gt;yield: Int = 1&lt;br /&gt;&lt;/pre&gt;Chalk up one more to the box of "pain points caused by using pattern matching for parallel assignment."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-180664142037494534?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/180664142037494534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2010/02/trick-of-day.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/180664142037494534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/180664142037494534'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2010/02/trick-of-day.html' title='Trick of the day'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-8507764331920740756</id><published>2010-02-03T14:57:00.003-07:00</published><updated>2010-02-04T11:45:17.440-07:00</updated><title type='text'>On Extraction</title><content type='html'>Scala case classes are great; they give you a tremendous leg up when it comes to implementing pattern matching. However, there's a drawback: the unapply method of case class companion objects take arguments of the type of the case class, and return Option[TupleN[...]] where N is the number of variables to the case class constructor. What's more, it's not possible to overload or override the unapply method to deconstruct other types of  by creating your own companion object on the side, as shown in this REPL session:&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&amp;gt; case class  Foo(val i: Int, val s: String)&lt;br /&gt;defined class Foo&lt;br /&gt;&lt;br /&gt;scala&amp;gt; object Foo {&lt;br /&gt;     |   def unapply(s: String): Option[Foo] = Some(new Foo(s.substring(0, 2).toInt, s.substring(2)))&lt;br /&gt;     | }&lt;br /&gt;defined module Foo&lt;br /&gt;&lt;br /&gt;scala&amp;gt; "12abcd" match {&lt;br /&gt;     |   case Foo(i, s) =&gt; println(s, i)&lt;br /&gt;     | }&lt;br /&gt;&amp;lt;console&amp;gt;:10: error: wrong number of arguments for object Foo&lt;br /&gt;         case Foo(i, s) =&gt; println(s, i)&lt;br /&gt;              ^&lt;br /&gt;&amp;lt;console&amp;gt;:10: error: wrong number of arguments for method println: (Any)Unit&lt;br /&gt;         case Foo(i, s) =&gt; println(s, i)&lt;br /&gt;&lt;/pre&gt;Sadly, it doesn't even seem to be possible to move this extractor to another class and get the desired result:&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&amp;gt; object SFoo {                                                                                 &lt;br /&gt;     |   def unapply(s: String): Option[Foo] = Some(new Foo(s.substring(0, 2).toInt, s.substring(2)))&lt;br /&gt;     | }&lt;br /&gt;defined module SFoo&lt;br /&gt;&lt;br /&gt;scala&amp;gt; "12abcd" match {                 &lt;br /&gt;     |   case SFoo(i, s) =&gt; println(s, i)&lt;br /&gt;     | }&lt;br /&gt;&amp;lt;console&amp;gt;:9: error: wrong number of arguments for object SFoo&lt;br /&gt;         case SFoo(i, s) =&gt; println(s, i)&lt;br /&gt;              ^&lt;br /&gt;&amp;lt;console&amp;gt;:9: error: wrong number of arguments for method println: (Any)Unit&lt;br /&gt;         case SFoo(i, s) =&gt; println(s, i)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Fortunately, there is a way around this issue: simply define your own class that extends ProductN! Then, you can define as many extractors as you want in different pseudo-companion objects and use them idiomatically:&lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&amp;gt; class Foo(val i: Int, val s: String) extends Product2[Int, String] {&lt;br /&gt;     |   val (_1, _2) = (i, s)&lt;br /&gt;     | }&lt;br /&gt;defined class Foo&lt;br /&gt;&lt;br /&gt;scala&amp;gt; object Foo {&lt;br /&gt;     |   def unapply(f: Foo): Option[(Int, String)] = Some((f.i, f.s))&lt;br /&gt;     | }&lt;br /&gt;defined module Foo&lt;br /&gt;&lt;br /&gt;scala&amp;gt; object SFoo {&lt;br /&gt;     |   def unapply(s: String): Option[Foo] = Some(new Foo(s.substring(0, 2).toInt, s.substring(2)))&lt;br /&gt;     | }&lt;br /&gt;defined module SFoo&lt;br /&gt;&lt;br /&gt;scala&amp;gt; "12abcd" match {&lt;br /&gt;     |   case SFoo(i, s) =&gt; println(s, i)&lt;br /&gt;     | }&lt;br /&gt;(abcd,12)&lt;br /&gt;&lt;br /&gt;scala&amp;gt; new Foo(1, "hi") match {&lt;br /&gt;     |   case Foo(i, s) =&gt; println(s, i)&lt;br /&gt;     | }&lt;br /&gt;(hi,1) &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Also, naturally, the trivial extractor (Foo =&gt; Foo) can supplant the Foo =&gt; Tuple2 extractor above: &lt;pre class="brush: scala"&gt;&lt;br /&gt;scala&amp;gt; object Foo {&lt;br /&gt;     |   def unapply(f: Foo): Option[Foo] = Some(f)&lt;br /&gt;     | }&lt;br /&gt;&lt;br /&gt;scala&amp;gt; new Foo(1, "hi") match {                  &lt;br /&gt;     |   case Foo(i, s) =&gt; println(s, i)         &lt;br /&gt;     | }                                &lt;br /&gt;(hi,1)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-8507764331920740756?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/8507764331920740756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2010/02/deconstructables.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/8507764331920740756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/8507764331920740756'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2010/02/deconstructables.html' title='On Extraction'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-8870705648236433543</id><published>2009-12-08T11:15:00.004-07:00</published><updated>2010-02-12T16:16:54.241-07:00</updated><title type='text'>A monadic Visitor</title><content type='html'>This Reader-esque monad emerged from my code this morning:&lt;pre class="brush: scala"&gt;&lt;br /&gt;trait A {&lt;br /&gt;  def accept[T](v: V[T]): T&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class B(val s: String) extends A {&lt;br /&gt;  var i = 0&lt;br /&gt;  override def accept[T](v: V[T]): T = v.visit(this)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class C(val s: String) extends A {&lt;br /&gt;  var i = 0&lt;br /&gt;  override def accept[T](v: V[T]): T = v.visit(this)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class D(val s: String) extends A {&lt;br /&gt;  var i = 0&lt;br /&gt;  override def accept[T](v: V[T]): T = v.visit(this)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;trait V[T] {&lt;br /&gt;  outer =&gt;&lt;br /&gt;  def visit(b: B): T&lt;br /&gt;  def visit(c: C): T&lt;br /&gt;  def visit(d: D): T&lt;br /&gt;&lt;br /&gt;  def map[U](f: T =&gt; U): V[U] = new V[U] {&lt;br /&gt;    def visit(b: B): U = f(outer.visit(b))&lt;br /&gt;    def visit(c: C): U = f(outer.visit(c))&lt;br /&gt;    def visit(d: D): U = f(outer.visit(d))&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def flatMap[U](f: T =&gt; V[U]): V[U]= new V[U] {&lt;br /&gt;    def visit(b: B): U = f(outer.visit(b)).visit(b)&lt;br /&gt;    def visit(c: C): U = f(outer.visit(c)).visit(c)&lt;br /&gt;    def visit(d: D): U = f(outer.visit(d)).visit(d)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object V {&lt;br /&gt;  def pure[T](t: T): V[T] = new V[T] {&lt;br /&gt;    def visit(b: B) = t&lt;br /&gt;    def visit(c: C) = t&lt;br /&gt;    def visit(d: D) = t&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;And the test:&lt;pre class="brush: scala"&gt;&lt;br /&gt;object Test {&lt;br /&gt;  def main(argv: Array[String]) {&lt;br /&gt;    class VI(i: Int) extends V[Int] {&lt;br /&gt;      def visit(b: B) = error("not supported")&lt;br /&gt;&lt;br /&gt;      def visit(c: C) = {&lt;br /&gt;        println("vi: " + c.s + " = " + c.i)&lt;br /&gt;        c.i = c.i + i&lt;br /&gt;        c.i&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      def visit(d: D) = {&lt;br /&gt;        println("vi: " + d.s + " = " + d.i)&lt;br /&gt;        d.i = d.i + i&lt;br /&gt;        d.i&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def f(i: Int): V[Int] = {&lt;br /&gt;      println("f: " + i)&lt;br /&gt;      new VI(i)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def g(i: Int): V[Int] = {&lt;br /&gt;      println("g: " + i)&lt;br /&gt;      new VI(i)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val c1: A = new C("c1")&lt;br /&gt;    val c2: A = new C("c2")&lt;br /&gt;    val d1: A = new D("d1")&lt;br /&gt;    val v = new VI(1)&lt;br /&gt;    println(c1.accept(v.flatMap(f).flatMap(g)))&lt;br /&gt;    println(c2.accept(v.flatMap(x =&gt; f(x).flatMap(g))))&lt;br /&gt;    println(d1.accept(v.flatMap(f).flatMap(g).flatMap(f).flatMap(g)))&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;As far as I can tell, this satisfies the monad laws. Am I missing anything? If not, this is the first monad I've "found in the wild!"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-8870705648236433543?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/8870705648236433543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2009/12/reader-monad-for-visitor-pattern.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/8870705648236433543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/8870705648236433543'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2009/12/reader-monad-for-visitor-pattern.html' title='A monadic Visitor'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-8833255815767484371</id><published>2009-12-02T21:30:00.003-07:00</published><updated>2010-06-13T21:37:42.266-06:00</updated><title type='text'>So much from so little</title><content type='html'>My solution to Tony's &lt;a href="http://blog.tmorris.net/debut-with-a-catamorphism/"&gt;catamorphism challenge&lt;/a&gt;:&lt;pre class="brush: scala"&gt;&lt;br /&gt;trait MyOption[+A] {&lt;br /&gt;  import MyOption._&lt;br /&gt;&lt;br /&gt;  def cata[X](some: A =&gt; X, none: =&gt; X): X&lt;br /&gt;  def map[B](f: A =&gt; B): MyOption[B] = cata(a =&gt; some(f(a)), none[B])&lt;br /&gt;  def flatMap[B](f: A =&gt; MyOption[B]): MyOption[B] = cata(f, none[B])&lt;br /&gt;  def getOrElse[AA &gt;: A](e: =&gt; AA): AA = cata(a =&gt; a, e)&lt;br /&gt;  def filter(p: A =&gt; Boolean): MyOption[A] = if (cata(p, false)) cata(a =&gt; some(a), none[A]) else none[A]&lt;br /&gt;  def foreach(f: A =&gt; Unit): Unit = cata(f, ())&lt;br /&gt;  def isDefined: Boolean = cata(_ =&gt; true, false)&lt;br /&gt;  def isEmpty: Boolean = cata(_ =&gt; false, true)&lt;br /&gt;  def get: A = cata(a =&gt; a, error("get on none"))&lt;br /&gt;  def orElse[AA &gt;: A](o: MyOption[AA]): MyOption[AA] = cata(a =&gt; some(a), o)&lt;br /&gt;  def toLeft[X](right: =&gt; X): Either[A, X] = cata(a =&gt; Left(a), Right(right))&lt;br /&gt;  def toRight[X](left: =&gt; X): Either[X, A] = cata(a =&gt; Right(a), Left(left))&lt;br /&gt;  def toList: List[A] = cata(a =&gt; List(a), Nil)&lt;br /&gt;  def iterator: Iterator[A] = toList.elements&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object MyOption {&lt;br /&gt;  def none[A] = new MyOption[A] {&lt;br /&gt;    def cata[X](s: A =&gt; X, n: =&gt; X) = n&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def some[A](a: A) = new MyOption[A] {&lt;br /&gt;    def cata[X](s: A =&gt; X, n: =&gt; X) = s(a)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-8833255815767484371?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/8833255815767484371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2009/12/catamorphisms-easy-peasy.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/8833255815767484371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/8833255815767484371'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2009/12/catamorphisms-easy-peasy.html' title='So much from so little'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-8240193704727961739</id><published>2009-11-07T15:02:00.003-07:00</published><updated>2009-11-07T15:10:57.372-07:00</updated><title type='text'>Composable Bindings in Lift, part II</title><content type='html'>&lt;p&gt;In my &lt;a href="http://logji.blogspot.com/2009/09/composable-bindings-in-lift.html"&gt;previous post&lt;/a&gt; I presented the DataBinding[T] type (T =&gt; NodeSeq =&gt; NodeSeq) and illustrated how classes inhabiting this type could be used along with an implicit binder function to create modular, reusable rendering logic for objects. In this post, I will discuss how to assemble these components and strategies for handling rendering over inheritance hierarchies.&lt;/p&gt;&lt;p&gt;I left off last time with this DataBinding trait:&lt;pre class="brush: scala"&gt;&lt;br /&gt;trait OrderBinding extends DataBinding[Order] {&lt;br /&gt;  implicit val userBinding: DataBinding[User]&lt;br /&gt;  implicit val addressBinding: DataBinding[Address]&lt;br /&gt;  implicit val lineBinding: DataBinding[OrderLine]&lt;br /&gt;  implicit val txnBinding: DataBinding[Transaction]&lt;br /&gt;&lt;br /&gt;  def apply(order: Order): Binding = (xhtml: NodeSeq) =&gt; {&lt;br /&gt;    val itemTemplate = chooseTemplate("order", "lineItem", xhtml)&lt;br /&gt;    val txnTemplate = chooseTemplate("order", "transaction", xhtml)&lt;br /&gt;&lt;br /&gt;    bind("order", xhtml,&lt;br /&gt;      "user" -&gt; order.user.bind("templates-hidden/user/order-display".path),&lt;br /&gt;      "shipTo" -&gt; order.shipTo.bind("templates-hidden/address/order-display".path),&lt;br /&gt;      "lineItems" -&gt; order.items.flatMap(_.bind(itemTemplate)).toSeq,&lt;br /&gt;      "transactions" -&gt; order.transactions.flatMap(_.bind(txnTemplate)).toSeq&lt;br /&gt;    )&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;This DataBinding[Order] is a trait, not an object like the previous binding instances. In addition, the other DataBinding instances that it delegates to are abstract implicit vals - meaning that I will need to create a concrete implementation of this trait to actually use it. The interesting thing here is that these vals are declared implicit within the scope of the trait, but do not need to be declared implicit when the trait is extended and made concrete. I can then compose what I want my binding to look like at the use site (say an ordinary snippet) like this:&lt;pre class="brush: scala"&gt;&lt;br /&gt;import Bindings._&lt;br /&gt;&lt;br /&gt;class MySnippet {&lt;br /&gt;  private implicit object ShowOrderBinding extends OrderBinding { &lt;br /&gt;    val userBinding = UserBinding&lt;br /&gt;    val addressBinding = MailingAddressBinding&lt;br /&gt;    val lineBinding = OrderLineBinding&lt;br /&gt;    val txnBinding = TransactionBinding //we'll implement this in a minute&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def showOrder(xhtml: NodeSeq): NodeSeq = {&lt;br /&gt;    val order: Order = //get an order from somewhere&lt;br /&gt;    order.bind(xhtml)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;The ShowOrderBinding selects the bindings I want for the components of the order in a declarative fashion, and since it is an implicit object in scope, it is selected as the DataBinding instance to render the order when order.bind is called. If I decide that I want to use the AdminAddressBinding from the previous post instead, I simply substitute it for MailingAddressBinding at the use site and I'm done!&lt;/p&gt;&lt;p&gt;There's one more thing that needs to be done in the above code - to implement TransactionBinding. This is a little tricky because there are several subclasses of Transaction that may be in the list of transactions for an order, so I'm going to need to recover type information about those instances at runtime in order to be able to choose the correct binding for a given Transaction. Furthermore, there's some information in the base Transaction type that I don't want to have to repeat bindings for in each subtype binding, so I'm going to use function composition to "add together" two different bindings.&lt;/p&gt;&lt;p&gt;There are two different approaches I'm going to show for how one might go about doing this: first, I'll try using a straightforward Scala match statement to figure out the object's type. That looks like this:&lt;pre class="brush: scala"&gt;&lt;br /&gt;trait TransactionBinding extends DataBinding[Transaction] {&lt;br /&gt;  implicit val authBinding: DataBinding[AuthTransaction]&lt;br /&gt;  implicit val captureBinding: DataBinding[CaptureTransaction]&lt;br /&gt;  implicit val shipBinig: DataBinding[ShipTransaction]&lt;br /&gt;&lt;br /&gt;  def apply(txn: Transaction): Binding = {&lt;br /&gt;    val base: Binding = bind("txn", _,&lt;br /&gt;      "scheduleDate" -&gt; Text(txn.scheduledAt.toString),&lt;br /&gt;      "completionDate" -&gt; Text(txn.completedAt.getOrElse("(incomplete)").toString),&lt;br /&gt;      "state" -&gt; Text(&lt;br /&gt;        txn.state match {&lt;br /&gt;          case COMPLETE =&gt; "complete"&lt;br /&gt;          case _ =&gt; "weird"&lt;br /&gt;        }&lt;br /&gt;      )&lt;br /&gt;    )&lt;br /&gt;&lt;br /&gt;    base compose (&lt;br /&gt;      txn match {&lt;br /&gt;        case auth: AuthTransaction =&gt; auth.binding&lt;br /&gt;        case capture: CaptureTransaction =&gt; capture.binding&lt;br /&gt;        case ship: ShipTransaction =&gt; ship.binding&lt;br /&gt;        case _ =&gt; error("Unrecognized transaction type!")&lt;br /&gt;      }&lt;br /&gt;    )&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Here, I've created a base binding that defines some simple behavior for how to bind elements that are common to all transactions. I then &lt;span style="font-style:italic;"&gt;compose&lt;/span&gt; that generated binding with a binding for the appropriate subclass. The determination of the subclass binding is of necessity a bit boilerplate-laden, but that's what happens when one throws away compile-time type information. The alternative, of course, would be to store each type of transaction in a separate collection associated with the order, but that's not the way I've gone for now.&lt;/p&gt;&lt;p&gt;There is, however, a hidden bug that may lurk in the pattern match above, depending upon your environment. Let's supposed for a minute that our model classes are persisted by Hibernate - and that the list of Transactions is annotated such that it is lazily, instead of eagerly, fetched from the database. In this case, the transactions returned may be translucently wrapped in runtime proxies. I say translucently instead of transparently because there is one critical respect in which a proxy does not behave in the same manner as the class being proxied - how it responds to the instanceof check that underlies the Scala pattern match. In this case, we will need to use a Visitor to correctly get the type for which we want to delegate binding. To do this, we'll modify our transaction classes as so:&lt;pre class="brush: scala"&gt;&lt;br /&gt;trait TransactionFunc[T] {&lt;br /&gt;  def apply(auth: AuthTransaction): T&lt;br /&gt;  def apply(capture: CaptureTransaction): T&lt;br /&gt;  def apply(ship: ShipTransaction): T&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;abstract class Transaction(val scheduledAt: DateTime, val completedAt: Option[DateTime], state: State) {&lt;br /&gt;  def accept[T](f: TransactionFunc[T]): T&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case class AuthTransaction(cc: CreditCard, amount: BigDecimal, scheduledAt: DateTime, completedAt: Option[DateTime], state: State) extends Transaction(scheduledAt, completedAt) {&lt;br /&gt;  def accept[T](f: TransactionFunc[T]): T = f.apply(this)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case class CaptureTransaction(auth: AuthTransaction, ...) extends Transaction(...)  {&lt;br /&gt;  def accept[T](f: TransactionFunc[T]): T = f.apply(this)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case class ShipTransaction(items: List[OrderLine], ...) extends Transaction(...)  {&lt;br /&gt;  def accept[T](f: TransactionFunc[T]): T = f.apply(this)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Then, the implementation of our transaction binding becomes this:&lt;pre class="brush: scala"&gt;&lt;br /&gt;trait TransactionBinding extends DataBinding[Transaction] {&lt;br /&gt;  implicit val authBinding: DataBinding[AuthTransaction]&lt;br /&gt;  implicit val captureBinding: DataBinding[CaptureTransaction]&lt;br /&gt;  implicit val shipBinig: DataBinding[ShipTransaction]&lt;br /&gt;&lt;br /&gt;  def apply(txn: Transaction): Binding = {&lt;br /&gt;    val base: Binding = //same as before...&lt;br /&gt;&lt;br /&gt;    base compose txn.accept(&lt;br /&gt;      new TransactionFunc[Binding] {&lt;br /&gt;        def apply(auth: AuthTransaction) = auth.binding&lt;br /&gt;        def apply(capture: CaptureTransaction) = capture.binding&lt;br /&gt;        def apply(ship: ShipTransaction) = ship.binding&lt;br /&gt;      }&lt;br /&gt;    )&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Since the correct overloading of TransactionFunc.apply will be statically determined, there is no possibility of a proxy getting in the way of our binding.&lt;/p&gt;&lt;p&gt;So, now we have a set of tools for binding composition. Here are some additional ideas of where this might be able to go, given the appropriate changes to Lift.&lt;/p&gt;&lt;p&gt;In my example of the &lt;b&gt;showOrder&lt;/b&gt; snippet above, the implementation is trivial... so trivial, in fact, that it almost doesn't need to be there. If the notion of a binding was fully integrated into Lift, we could make Loc somewhat more powerful. Loc is one of the primary classes in Lift used to generate the SiteMap, which declares what paths are accessible within a Lift application. A path in a Loc typically corresponds to the path to an XML template that will specify the snippets and markup for a request. An important thing to note though is that Loc is not simply Loc - it is in fact Loc[T], where by default T is NullLocParams, a meaningless object essentially equivalent to Unit. &lt;/p&gt;&lt;p&gt;When one looks at making T something other than Unit, Loc starts to become significantly more interesting - first, it declares a rewrite method that can be overriden to populate the Loc with an instance of T as part of its processing, and secondly, Loc can specify explicitly the template to be used to render the Loc, instead of using the one that corresponds to the path. Wait... we have an instance, and we have a template... what if we could specify a DataBinding[T] as well? In this case, we might not need for there to be a snippet at all!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-8240193704727961739?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/8240193704727961739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2009/10/composable-bindings-in-lift-part-ii.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/8240193704727961739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/8240193704727961739'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2009/10/composable-bindings-in-lift-part-ii.html' title='Composable Bindings in Lift, part II'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-7751725796690283925</id><published>2009-09-29T17:53:00.010-06:00</published><updated>2009-11-07T13:55:21.191-07:00</updated><title type='text'>Composable bindings in Lift</title><content type='html'>I've been using &lt;a href="http://liftweb.net"&gt;Lift&lt;/a&gt; as the framework behind a small internal web application at my company for the past year or so. The experience has been generally positive, despite a few quibbles I have with how state is typically maintained and passed around within an application. &lt;br /&gt;&lt;br /&gt;Lift takes a "view first" approach to building web applications, as opposed to the commonly favored MVC pattern. In practice, "view first" boils down to essentially this: when you create an XHTML template for a page, that template will contain one or more XML tags where the name of the tag refers to a method to be called with the body of the tag as an argument. Such a method will return the XHTML to be substituted in place of the original tag and its contents. In Lift parlance such a method is called a "snippet," and has the type NodeSeq =&gt; NodeSeq. In order to more fully understand the rest of this article, I recommend you read more about snippets &lt;a href="http://liftweb.net/docs/getting_started/mod_master.html#x1-110002.5"&gt;here&lt;/a&gt; if you're not already familiar with them.&lt;br /&gt;&lt;br /&gt;The interesting thing about this signature is that functions with this type can easily be composed. What's more, the method most frequently used to implement snippets, BindHelpers.bind, can be partially applied to its arguments to give a closure with the same signature. &lt;br /&gt;&lt;br /&gt;When I'm designing a website, most of the time rendering a page (or even a snippet within a page) isn't about displaying the data from a single object - instead, I often want to render a whole object graph. Ideally, I want to be able to choose a rendering for each type of object I'm concerned with, then compose these elements to produce the final page. Templates for objects should be reusable and modular, and for any given page I should be able to pick between multiple renderings of any given object, in some places displaying a concise summary and elsewhere a detailed exposition of all the available data. &lt;br /&gt;&lt;br /&gt;Furthermore, while I believe that "the meaning should belong with the bytes" I also think that the rendering should be as decoupled from the bytes as possible to allow for maximum flexibility. Hence, I don't want my model classes to have any sort of "render" method - the display is something that should be layered on above the semantics provided by the names and types of the members of the object.&lt;br /&gt;&lt;br /&gt;With these goals and composition in mind, I started with the following tiny bit of code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;import net.liftweb.http.TemplateFinder.findAnyTemplate&lt;br /&gt;import net.liftweb.util.{Box,Full,Empty,Failure,Log}&lt;br /&gt;import scala.xml._&lt;br /&gt;&lt;br /&gt;object Bindings {&lt;br /&gt;   type Binding = NodeSeq =&gt; NodeSeq&lt;br /&gt;&lt;br /&gt;   type DataBinding[T] = T =&gt; NodeSeq =&gt; NodeSeq&lt;br /&gt;&lt;br /&gt;   //adds a bind() function to an object if an implicit DataBinding is available for that object&lt;br /&gt;   implicit def binder[T](t: T)(implicit binding: DataBinding[T]): Binder = Binder(binding(t))&lt;br /&gt;   implicit def binder(binding: Binding): Binder = Binder(binding)&lt;br /&gt;&lt;br /&gt;   //decorator for a binding function that allows it to be called as bind() rather than apply()&lt;br /&gt;   //and also provides facilities for binding to a specific template&lt;br /&gt;   case class Binder(val binding: Binding) {&lt;br /&gt;       def bind(xhtml: NodeSeq): NodeSeq = binding.apply(xhtml)&lt;br /&gt;       def bind(templatePath: List[String]): NodeSeq = {&lt;br /&gt;           findAnyTemplate(templatePath) map binding match {&lt;br /&gt;               case Full(xhtml) =&gt; xhtml&lt;br /&gt;               case Failure(msg, ex, _) =&gt; Text(ex.map(_.getMessage).openOr(msg))&lt;br /&gt;               case Empty =&gt; Text("Unable to find template with path " + templatePath.mkString("/", "/", ""))&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   object NullBinding extends Binding {&lt;br /&gt;       override def apply(xhtml : NodeSeq) : NodeSeq = NodeSeq.Empty&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   object StringBinding extends DataBinding[String] {&lt;br /&gt;       override def apply(msg: String) = (xhtml: NodeSeq) =&gt; Text(msg)&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   implicit def path2list(s: String) = new {&lt;br /&gt;     def path: List[String] = s.split("/").toList&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The principle idea is that in my application, I will create one or more DataBinding instances for each of my model types, and that then by simply declaring an implicit val containing the instance I want in the narrowest scope possible, I can call .bind on any object for which an implicit DataBinding is available, or .binding if I want to compose multiple such binding functions and close over the model instance. Furthermore, this gives me good ways to compose both over composition and inheritance hierarchies, as I'll show below. &lt;br /&gt;&lt;br /&gt;Consider that I have the following simplified, store-oriented model objects. In Lift, these would probably be implemented using Mapper or JPA - in the app that I've been working on, these are Java classes persisted by Hibernate - certainly not things that I want to change in order to support rendering by Scala.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;case class User(fname: String, lname: String, email: String, joinedOn: DateTime)&lt;br /&gt;case class Address(&lt;br /&gt;  recipient: String, &lt;br /&gt;  addr1: String, &lt;br /&gt;  addr2: String, &lt;br /&gt;  city: String, &lt;br /&gt;  state: String, &lt;br /&gt;  country: String, &lt;br /&gt;  postalCode: String&lt;br /&gt;)&lt;br /&gt;case class Product(name: String, basePrice: BigDecimal, shippingCost: Option[BigDecimal])&lt;br /&gt;case class OrderLine(product: Product, quantity: Int)&lt;br /&gt;class Order(&lt;br /&gt;  val user: User, &lt;br /&gt;  val placedOn: DateTime, &lt;br /&gt;  val shipTo: Address, &lt;br /&gt;  var items: List[OrderLine], &lt;br /&gt;  var transactions: List[Transaction]&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;sealed trait State&lt;br /&gt;object PENDING extends State&lt;br /&gt;object IN_PROGRESS extends State&lt;br /&gt;object COMPLETE extends State&lt;br /&gt;object FAILED extends State&lt;br /&gt;object CANCELED extends State&lt;br /&gt;&lt;br /&gt;abstract class Transaction(val scheduledAt: DateTime, val completedAt: Option[DateTime], state: State)&lt;br /&gt;case class AuthTransaction(&lt;br /&gt;  cc: CreditCard, &lt;br /&gt;  amount: BigDecimal, &lt;br /&gt;  scheduledAt: DateTime, &lt;br /&gt;  completedAt: Option[DateTime], &lt;br /&gt;  state: State&lt;br /&gt;) extends Transaction(scheduledAt, completedAt)&lt;br /&gt;case class CaptureTransaction(auth: AuthTransaction, ...) extends Transaction(...)&lt;br /&gt;case class ShipTransaction(items: List[OrderLine], ...) extends Transaction(...)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With this set of models, I have a few different ways that they will be rendered - the display to the users will not be the same as the display to site administrators, I may (or may not) want to reuse the same rendering code for a line item in an order as in a shipping transaction, and so forth. Let's take a look at how this ends up.&lt;br /&gt;&lt;br /&gt;First, I want to create some DataBinding objects for my classes that are built just on primitive types. Let's start with User.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;import net.liftweb.util.Helpers._ //this is where BindHelpers.bind comes from&lt;br /&gt;import scala.xml._&lt;br /&gt;import Bindings._&lt;br /&gt;&lt;br /&gt;object UserBinding extends DataBinding[User] {&lt;br /&gt;  def apply(user: User): Binding = bind("user", _,&lt;br /&gt;    "name" -&gt; Text(user.fname+" "+user.lname),&lt;br /&gt;    "email" -&gt; Text(user.email)&lt;br /&gt;  )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object MailingAddressBinding extends DataBinding[Address] {&lt;br /&gt;  def apply(addr: Address): Binding = bind("address", _,&lt;br /&gt;    "line1" -&gt; Text(addr.recipient),&lt;br /&gt;    "line2" -&gt; Text(addr.addr1),&lt;br /&gt;    "line3" -&gt; Text(addr.addr2),&lt;br /&gt;    "line4" -&gt; Text(addr.city+", "+addr.state+" "+addr.postalCode+" "+addr.country)&lt;br /&gt;  )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object AdminAddressBinding extends DataBinding[Address] {&lt;br /&gt;  def apply(addr: Address): Binding = bind("address", _,&lt;br /&gt;    "recipient" -&gt; Text(addr.recipient),&lt;br /&gt;    // imagine more literal bindings like the previous one here&lt;br /&gt;  )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object OrderLineBinding extends DataBinding[OrderLine] {&lt;br /&gt;  //more of the same&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;These implementations take advantage of partial application and the Scala type inferencer to turn the call to bind(...) into a closure with the type Binding, which is NodeSeq =&gt; NodeSeq. At this point, we're not taking advantage of the fact that these functions can compose, so we'll do so now a we build bindings for our more complex objects. &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;//same imports as before&lt;br /&gt;&lt;br /&gt;trait OrderBinding extends DataBinding[Order] {&lt;br /&gt;  implicit val userBinding: DataBinding[User]&lt;br /&gt;  implicit val addressBinding: DataBinding[Address]&lt;br /&gt;  implicit val lineBinding: DataBinding[OrderLine]&lt;br /&gt;  implicit val txnBinding: DataBinding[Transaction]&lt;br /&gt;&lt;br /&gt;  def apply(order: Order): Binding = (xhtml: NodeSeq) =&gt; {&lt;br /&gt;    val itemTemplate = chooseTemplate("order", "lineItem", xhtml)&lt;br /&gt;    val txnTemplate = chooseTemplate("order", "transaction", xhtml)&lt;br /&gt;&lt;br /&gt;    bind("order", xhtml,&lt;br /&gt;      "user" -&gt; order.user.bind("templates-hidden/user/order-display".path),&lt;br /&gt;      "shipTo" -&gt; order.shipTo.bind("templates-hidden/address/order-display".path),&lt;br /&gt;      "lineItems" -&gt; order.items.flatMap(_.bind(itemTemplate)).toSeq,&lt;br /&gt;      "transactions" -&gt; order.transactions.flatMap(_.bind(txnTemplate)).toSeq&lt;br /&gt;    )&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There's a lot more going on in this one. First off, we define our DataBinding as a trait rather than a concrete object, in order to take advantage of abstract implicit val declarations. When we go to instantiate this trait, we will provide concrete implementations of the various bindings that we want applied to the objects from which an Order instance is composed. The compiler will then be able to apply the "binder" conversion to get a Binder instance which closes over the instance with the appropriate DataBinding so that we can simply call instance.bind and pass either a path to a template, or a chunk of XHTML extracted from the input with chooseTemplate to get our final value.&lt;br /&gt;&lt;br /&gt;To be continued...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-7751725796690283925?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/7751725796690283925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2009/09/composable-bindings-in-lift.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/7751725796690283925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/7751725796690283925'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2009/09/composable-bindings-in-lift.html' title='Composable bindings in Lift'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-4284788475555425748</id><published>2009-04-24T09:54:00.002-06:00</published><updated>2009-04-24T09:56:20.145-06:00</updated><title type='text'>Paulp speaks great truth</title><content type='html'>"After you have spent a certain amount of time in the compiler, you will&lt;br /&gt;come to feel angry resentment at every comment you encounter, because it&lt;br /&gt;might be trying to mislead you! I have modified my editor not to show me&lt;br /&gt;any comments in scala sources so they cannot tempt me with their siren&lt;br /&gt;songs of reasons and explanations.  AH THE LIMITLESS SERENITY"&lt;br /&gt;&lt;br /&gt;Seems to me that this technique is much more widely applicable than just to scala internals...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-4284788475555425748?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/4284788475555425748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2009/04/paulp-speaks-great-truth.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/4284788475555425748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/4284788475555425748'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2009/04/paulp-speaks-great-truth.html' title='Paulp speaks great truth'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-3620665692177495449</id><published>2009-04-21T21:12:00.010-06:00</published><updated>2009-11-07T13:40:46.584-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='constructors'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Deconstruct(or)ing Scala</title><content type='html'>The question of whether to use a constructor or a factory method for object construction is not new; we've had this discussion for years in the Java community. Scala's approach to object construction has a few features that will undoubtedly reignite this debate.&lt;br /&gt;&lt;br /&gt;On the one hand, ordinary object construction is significantly more powerful than in Java - first, the all the ordinary Java boilerplate of assigning constructor parameters to member variables is abolished. What in Java would look like this:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;public class Foo {&lt;br /&gt;  final int myInt;&lt;br /&gt;  final String myString;&lt;br /&gt;&lt;br /&gt;  public Foo(int myInt, String myString) {&lt;br /&gt;    this.myInt = myInt;&lt;br /&gt;    this.myString = myString;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;becomes the concise and sensible&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;class Foo(val myInt: Int, val myString: String)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;More significantly, Scala's trait mechanism allows for extension of a class definition at the use site; for example, if I have a trait that adds rendering logic to a class, I can mix it in only when I need it.&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;trait FooRenderer extends Foo {&lt;br /&gt;  def render: String = "I'm a Foo! My int is "+myInt+" and my string is "+myString&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;val f1 = new Foo(1, "hi") // normal Foo&lt;br /&gt;val f2 = new Foo(2, "well, hello!") with FooRenderer // renderable Foo&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So Scala's constructors are really powerful and you really want to use them, right? But wait...&lt;br /&gt;&lt;br /&gt;It turns out that there are some subtle issues that arise if you start adding more logic to constructors in Scala. The logic of a Scala constructor goes directly in the body of the class, and here's the tricky bit: this is also where other member variables that aren't just blindly assigned as constructor parameters are declared and assigned. In Java, any intermediate variables that you used within a constructor were unavoiably local; in Scala they can easily (and will, if care is not taken) become a permanent part of the object. &lt;br /&gt;&lt;br /&gt;Let's look at something a little more complex. Consider a class that, as part of its construction, finds the most common element in a list and assigns both that element and the number of occurrences to member variables.&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;class Common[T](l: Iterable[T]) {&lt;br /&gt;  val (value, count) = l.foldLeft(Map.empty[T,Int]) {(m, v) =&gt;&lt;br /&gt;    m + (v -&gt; (m.getOrElse(v, 0) + 1))&lt;br /&gt;  }.reduceLeft {(a, b) =&gt;&lt;br /&gt;    if (a._2 &gt; b._2) a else b&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, there may be ways to implement this that avoid constructing and decomposing a tuple, but this is the most straightforward and efficient implementation I could come up with. A peek at the generated bytecode reveals something interesting, however:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   93: putfield #83; //Field x$1:Lscala/Tuple2;&lt;br /&gt;   96: aload_0&lt;br /&gt;   97: aload_0&lt;br /&gt;   98: getfield #83; //Field x$1:Lscala/Tuple2;&lt;br /&gt;   101: invokevirtual #73; //Method scala/Tuple2._1:()Ljava/lang/Object;&lt;br /&gt;   104: putfield #85; //Field value:Ljava/lang/Object;&lt;br /&gt;   107: aload_0&lt;br /&gt;   108: aload_0&lt;br /&gt;   109: getfield #83; //Field x$1:Lscala/Tuple2;&lt;br /&gt;   112: invokevirtual #76; //Method scala/Tuple2._2:()Ljava/lang/Object;&lt;br /&gt;   115: invokestatic #91; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I&lt;br /&gt;   118: putfield #93; //Field count:I&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What's up with line 93? I didn't want that spurious Tuple2 to hang around as a member field - I just needed it as an intermediate value in the construction of the object!&lt;br /&gt;&lt;br /&gt;As it turns out, this problem is not restricted to tuples; if you use intermediate variables in the construction of your objects, they will become permanent residents. This may not be a real problem in most circumstances, but it feels messy. Now, the standard thing to do in this situation would to be to create a factory method on the companion object:&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;object Common {&lt;br /&gt;  def apply[T](l: Iterable[T]): Common[T] = {&lt;br /&gt;    val (value, count) = l.foldLeft(Map.empty[T,Int]) {(m, v) =&gt;&lt;br /&gt;      m + (v -&gt; (m.getOrElse(v, 0) + 1))&lt;br /&gt;    }.reduceLeft {(a, b) =&gt;&lt;br /&gt;      if (a._2 &gt; b._2) a else b&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    new Common(value, count)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Common[T](val value: T, val count: Int)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now there's no intermediate variable stored in the bytecode for Common, but we have a new problem: we can no longer construct the object from an iterable while mixing in an additional trait at the instantiation site!&lt;br /&gt;&lt;br /&gt;Scala supports the use of auxiliary constructors, with the caveat (similar to that present in Java) that the first statement in an auxiliary constructor must be either a call to the primary constructor, or another auxiliary constructor. Because of this constraint, we can't simply use the contents of the factory method above in an auxiliary constructor. We can, however, evaluate a method within the chained call, and that gives us a workable, if somewhat boilerplate-laden solution.&lt;br /&gt;&lt;pre class="brush: scala"&gt;&lt;br /&gt;class Common[T](val value: T, val count: Int) {&lt;br /&gt;&lt;br /&gt;  private def this(t: Tuple2[T, Int]) = this(t._1, t._2)&lt;br /&gt;&lt;br /&gt;  def this(l: Iterable[T]) = this(&lt;br /&gt;    l.foldLeft(Map.empty[T,Int]) {(m, v) =&gt;&lt;br /&gt;      m + (v -&gt; (m.getOrElse(v, 0) + 1))&lt;br /&gt;    }.reduceLeft {(a, b) =&gt;&lt;br /&gt;      if (a._2 &gt; b._2) a else b&lt;br /&gt;    }&lt;br /&gt;  )&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;By threading the decomposition through a private constructor that takes a tuple, we can now avoid the spurious intermediate values getting incorporated into the class, and still enjoy the benefits of instantiation-site mix-ins. What's more, there has been a bunch of talk on the Scala mailing list about a future unification of tuples with method (and hopefully constructor) parameters - in which event the extra private constructor could disappear entirely!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-3620665692177495449?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://logji.blogspot.com/feeds/3620665692177495449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://logji.blogspot.com/2009/04/deconstructoring-scala.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/3620665692177495449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/3620665692177495449'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2009/04/deconstructoring-scala.html' title='Deconstruct(or)ing Scala'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-3745504192368183584</id><published>2009-04-15T21:38:00.003-06:00</published><updated>2009-04-22T11:36:16.392-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='koan'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>A Scala Koan</title><content type='html'>I just came across this post from &lt;a href="http://james-iry.blogspot.com"&gt;James Iry&lt;/a&gt; on the Scala list. &lt;br /&gt;&lt;br /&gt;"It's not part of the language so you write your own and decide if it's too confusing to be useful."&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class LazyVar[T](init : =&gt; T) {&lt;br /&gt;  private var thunk : (() =&gt; T) = {() =&gt; {thunk = {() =&gt; init}; thunk()}}&lt;br /&gt;   &lt;br /&gt;  def ! = synchronized { thunk() }&lt;br /&gt;  def :=(newVal : =&gt; T) = synchronized { thunk = {() =&gt; {thunk = {() =&gt; newVal}; thunk()}}}&lt;br /&gt;   &lt;br /&gt;  def morph(f : T =&gt; T) = synchronized { val oldThunk = thunk ; thunk = { () =&gt; { thunk = {() =&gt; f(oldThunk())}; thunk()}}}                        &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object LazyVar {&lt;br /&gt;  def apply[T](init : =&gt; T) = new LazyVar({init})&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;scala&gt; val x = LazyVar(1)&lt;br /&gt;x: LazyVar[Int] = LazyVar@5354a&lt;br /&gt;&lt;br /&gt;scala&gt; x := {println("assigning 2"); 2}&lt;br /&gt;&lt;br /&gt;scala&gt; x := {println("assigning 3"); 3}&lt;br /&gt;&lt;br /&gt;scala&gt; x!&lt;br /&gt;assigning 3&lt;br /&gt;res16: Int = 3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It's a Scala koan!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-3745504192368183584?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/3745504192368183584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/3745504192368183584'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2009/04/scala-koan.html' title='A Scala Koan'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-5274446328438620755</id><published>2007-12-05T16:08:00.000-07:00</published><updated>2007-12-05T16:14:35.318-07:00</updated><title type='text'></title><content type='html'>In looking around the web a bit, I've had a hard time finding any capistrano plugins that handle deployment of SVN tags and branches well. So, I wrote a little one of my own.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;Capistrano.configuration(:must_exist).load do&lt;br /&gt;&lt;br /&gt;  set :svn_trunk_dir, 'trunk'&lt;br /&gt;  set :svn_tag_dir, 'tags'&lt;br /&gt;  set :svn_branch_dir, 'branches'&lt;br /&gt;  &lt;br /&gt;  before "deploy" do&lt;br /&gt;    if rails_env == 'production'&lt;br /&gt;      abort "ERROR: Production deploys must be from a tag or branch." unless repository =~ /#{svn_tag_dir}|#{svn_branch_dir}/&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  desc &lt;&lt;-DESC &lt;br /&gt;  Deploy from a tag instead of from the trunk. This will prompt if no TAG value &lt;br /&gt;  is specified on the command line. No sanity checks for whether the tag actually&lt;br /&gt;  exists are performed.&lt;br /&gt;  DESC&lt;br /&gt;  task :deploy_tag do&lt;br /&gt;    set :repository, get_svn_url(svn_tag_dir, 'TAG')&lt;br /&gt;    run_deploy&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  desc "Create the specified tag and deploy from that tag."&lt;br /&gt;  task :deploy_new_tag do&lt;br /&gt;    trunk = "#{repository[/(.*?)(?:\/trunk)?$/, 1]}/#{svn_trunk_dir}"&lt;br /&gt;    set :repository, get_svn_url(svn_tag_dir, 'TAG')&lt;br /&gt;    puts "Creating new tagged release of trunk as #{ENV['TAG']}."&lt;br /&gt;    system "svn cp #{trunk} #{repository}"&lt;br /&gt;    run_deploy&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  desc "Deploy from a branch instead of a tag; same caviats as for :deploy_tag."&lt;br /&gt;  task :deploy_branch do&lt;br /&gt;    set :repository, get_svn_url(svn_branch_dir, 'BRANCH')&lt;br /&gt;    run_deploy&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  desc "Create a branch from the specified tag and deploy from that branch."&lt;br /&gt;  task :deploy_new_branch do&lt;br /&gt;    tag_url = get_svn_url(svn_tag_dir, 'TAG')&lt;br /&gt;    branch_url = get_svn_url(svn_branch_dir, 'BRANCH')&lt;br /&gt;    puts "Creating new branch #{ENV['BRANCH']} from tag #{ENV['TAG']}."&lt;br /&gt;    system "svn cp #{tag_url} #{branch_url}"&lt;br /&gt;    set :repository, branch_url&lt;br /&gt;    run_deploy    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  # Executes the ordinary deploy task&lt;br /&gt;  def run_deploy&lt;br /&gt;    puts "Deploying using repository url #{repository}"&lt;br /&gt;    execute_task(find_task("deploy"))&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  # Prompts the user for a tag and updates the repository url based upon that&lt;br /&gt;  # tag and the svn conventions.&lt;br /&gt;  def get_svn_url(tag_dir, env_var = 'TAG')&lt;br /&gt;    while ENV[env_var].nil? || ENV[env_var].strip.empty?&lt;br /&gt;      ENV[env_var] = Capistrano::CLI.ui.ask("Please specify #{env_var.downcase} name: ")&lt;br /&gt;      ENV[env_var].strip!&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    repo_root = repository[/(.*?)(?:\/trunk)?$/, 1]&lt;br /&gt;    "#{repo_root}/#{tag_dir}/#{ENV[env_var]}"&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I just stuck all of this in lib/cap/tag_deployer.rb, then added &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require 'lib/cap/tag_deployer.rb'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;to my deploy.rb file, and away I go!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-5274446328438620755?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/5274446328438620755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/5274446328438620755'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2007/12/in-looking-around-web-bit-ive-had-hard.html' title=''/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author></entry><entry><id>tag:blogger.com,1999:blog-8515489.post-116563362543002762</id><published>2006-12-08T20:04:00.000-07:00</published><updated>2006-12-08T20:07:05.440-07:00</updated><title type='text'>XML is a social tool</title><content type='html'>Yesterday, I was listening to a presentation where XML was presented as a solution to some technical problem. Now, don't get me wrong, I like XML, but I'd like to make one thing perfectly clear.&lt;br /&gt;&lt;br /&gt;XML is a solution to exactly 0 technical problems. It is, however, a reasonable answer to many social problems of software development.&lt;br /&gt;&lt;br /&gt;But not any techical ones. Period.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8515489-116563362543002762?l=logji.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/116563362543002762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8515489/posts/default/116563362543002762'/><link rel='alternate' type='text/html' href='http://logji.blogspot.com/2006/12/xml-is-social-tool.html' title='XML is a social tool'/><author><name>Kris Nuttycombe</name><uri>http://www.blogger.com/profile/06347383351250086727</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/-Ch7oX2TWoLk/TmWpO6QFWtI/AAAAAAAAAIE/ek3lWAK_gKY/s220/Portrait-Kris.JPG'/></author></entry></feed>
