<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chuusai</title>
	<atom:link href="http://www.chuusai.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.chuusai.com</link>
	<description>Scala Consultancy &#38; Training</description>
	<lastBuildDate>Mon, 20 Feb 2012 22:30:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Type-level selection sort in shapeless</title>
		<link>http://www.chuusai.com/2012/01/27/type-level-sorting-in-shapeless/</link>
		<comments>http://www.chuusai.com/2012/01/27/type-level-sorting-in-shapeless/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 14:07:54 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=134</guid>
		<description><![CDATA[To celebrate my talk on shapeless being selected for this year&#8217;s Northeast Scala Symposium in Boston, I thought I&#8217;d share something entertaining (and slightly whimsical) with you &#8212; compile time selection sort at the type-level! Selection sort is just about the simplest possible sorting algorithm &#8212; select the least element from your unsorted list as<a href="http://www.chuusai.com/2012/01/27/type-level-sorting-in-shapeless/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>To celebrate my <a href="http://www.chuusai.com/event/shapeless-nescala-2012/">talk</a> on <a target="_blank" href="https://github.com/milessabin/shapeless">shapeless</a> being selected for this year&#8217;s <a target="_blank" href="http://nescala.org/">Northeast Scala Symposium</a> in Boston, I thought I&#8217;d share something entertaining (and slightly whimsical) with you &mdash; compile time selection sort at the type-level!</p>
<p><a target="_blank" href="http://en.wikipedia.org/wiki/Selection_sort">Selection sort</a> is just about the simplest possible sorting algorithm &mdash; select the least element from your unsorted list as the first element of the sorted list, then recursively sort the remainder &mdash; so I&#8217;ll take it as a given, and focus on the interesting bit &#8230; how can this <em>possibly</em> be done at the type-level?</p>
<p>The first thing we need is a type-level representation of lists of sortable things. For that, we&#8217;re going to use <a target="_blank" href="https://github.com/milessabin/shapeless/blob/topic/tuples/src/main/scala/shapeless/hlist.scala"><span class="prettyprint">HList</span></a>s of type-level <a target="_blank" href="https://github.com/milessabin/shapeless/blob/topic/tuples/src/main/scala/shapeless/nat.scala">natural numbers</a>.</p>
<pre class="dontquote prettyprint lang-scala">
import shapeless._
import Nat._
import HList._

def typed[T](t : => T) {}

val unsorted = _3 :: _1 :: _4 :: _0 :: _2 :: HNil
typed[_3 :: _1 :: _4 :: _0 :: _2 :: HNil](unsorted)
</pre>
<p>Here <span class="prettyprint">unsorted</span> is a value-level list of <span class="prettyprint">Nat</span>&#8216;s, and we can see that its structure is exactly mirrored in its type &mdash; in shapeless each <span class="prettyprint">Nat</span> value (<span class="prettyprint">_0</span>, <span class="prettyprint">_1</span>, &#8230;) has a corresponding <span class="prettyprint">Nat</span> type with the same name (<span class="prettyprint">_0</span>, <span class="prettyprint">_1</span>, &#8230;). We use the <span class="prettyprint">typed</span> function here to verify the type of <span class="prettyprint">unsorted</span> rather than use a type annotation on its val declaration to ensure that the act of verifying the inferred type doesn&#8217;t itself contribute to type inference.</p>
<p>Now we need a way of capturing order over these type-level <span class="prettyprint">Nat</span>&#8216;s. We do that using a type class that witnesses the relationship at the type level,</p>
<pre class="dontquote prettyprint lang-scala">
trait LTEq[A <: Nat, B <: Nat]

object LTEq {
  import Nat._0

  type <=[A <: Nat, B <: Nat] = LTEq[A, B]

  implicit def ltEq1 = new <=[_0, _0] {}
  implicit def ltEq2[B <: Nat] = new <=[_0, Succ[B]] {}
  implicit def ltEq3[A <: Nat, B <: Nat](implicit lt : A <= B) =
    new <=[Succ[A], Succ[B]] {}
}
</pre>
<p>If you're familiar with <a target="_blank" href="http://en.wikipedia.org/wiki/Peano_axioms">Peano arithmetic</a> it should be pretty clear how this works &mdash; we have two base cases: <span class="prettyprint">_0</span> is less than or equal to <span class="prettyprint">_0</span>, and <span class="prettyprint">_0</span> is less than or equal to the successor of any number; and we have one induction case: if <span class="prettyprint">A <= B</span> then <span class="prettyprint">A+1 <= B+1</span>. With these definitions in place, the magic of Scala's implicit resolution allows us to ask the compiler about relationships between different <span class="prettyprint">Nat</span> types,</p>
<pre class="dontquote prettyprint lang-scala">
scala> import shapeless._ ; import Nat._ ; import LTEq._
import shapeless._
import Nat._
import LTEq._

scala> implicitly[_2 <= _5] // OK
res0: shapeless.LTEq.<=[shapeless.Nat._2,shapeless.Nat._5] =
  shapeless.LTEq$$anon$5@4fc8927c

scala> implicitly[_4 <= _2] // Does not compile
<console>:17: error: could not find implicit value for parameter
  e: shapeless.LTEq.<=[shapeless.Nat._4,shapeless.Nat._2]
    implicitly[_4 <= _2]
              ^
</pre>
<p>Before we go any further, let's define an operation which witnesses whether or not an <span class="prettyprint">HList</span> of <span class="prettyprint">Nat</span>s is in sorted order &mdash; we'll want this to verify that our type-level sort is correct,</p>
<pre class="dontquote prettyprint lang-scala">
trait NonDecreasing[L <: HList]
implicit def hnilNonDecreasing = new NonDecreasing[HNil] {}
implicit def hlistNonDecreasing1[H] = new NonDecreasing[H :: HNil] {}
implicit def hlistNonDecreasing2[H1 <: Nat, H2 <: Nat, T <: HList]
  (implicit ltEq : H1 <= H2, ndt : NonDecreasing[H2 :: T]) =
    new NonDecreasing[H1 :: H2 :: T] {}

def acceptNonDecreasing[L <: HList](l : L)(implicit ni : NonDecreasing[L]) = l

// Verify type-level relations
implicitly[NonDecreasing[_1 :: _2 :: _3 :: HNil]]   // OK
implicitly[NonDecreasing[_1 :: _3 :: _2 :: HNil]]   // Does not compile

// Apply at the value-level
acceptNonDecreasing(_1 :: _2 :: _3 :: HNil)         // OK
acceptNonDecreasing(_1 :: _3 :: _2 :: HNil)         // Does not compile
</pre>
<p>This is a fairly straighforward induction &mdash; we have two base cases: an empty list is in sorted order, as is a list of exactly one element; and we have one induction case: a list is in sorted order if its tail is, and if its first element is less than or equal to its second element.</p>
<p>Now we can define an operation to select the least element from an <span class="prettyprint">HList</span> of <span class="prettyprint">Nat</span>s, returning both it and the remainder of the list,</p>
<pre class="dontquote prettyprint lang-scala">
trait SelectLeast[L <: HList, M <: Nat, Rem <: HList] {
  def apply(l : L) : (M, Rem)
}

trait LowPrioritySelectLeast {
  implicit def hlistSelectLeast1[H <: Nat, T <: HList] =
    new SelectLeast[H :: T, H, T] {
      def apply(l : H :: T) : (H, T) = (l.head, l.tail)
    }
}

object SelectLeast extends LowPrioritySelectLeast {
  implicit def hlistSelectLeast3[H <: Nat, T <: HList, TM <: Nat, TRem <: HList]
    (implicit tsl : SelectLeast[T, TM, TRem], ev : TM < H) =
      new SelectLeast[H :: T, TM, H :: TRem] {
        def apply(l : H :: T) : (TM, H :: TRem) = {
          val (tm, rem) = tsl(l.tail)
          (tm, l.head :: rem)
        }
      }
}

val (l1, r1) = selectLeast(_1 :: _2 :: _3 :: HNil)
typed[_1](l1)
typed[_2 :: _3 :: HNil](r1)

val (l2, r2) = selectLeast(_3 :: _1 :: _4 :: _0 :: _2 :: HNil)
typed[_0](l2)
typed[_3 :: _1 :: _4 :: _2 :: HNil](r2)
</pre>
<p>Here're we're working at both the type-level and at the value-level &mdash; we're selecting the least value-level <span class="prettyprint">Nat</span> from each of the examples <span class="prettyprint">HList</span>s, and these are being assigned the corresponding <span class="prettyprint">Nat</span> types. Hopefully the recursive pattern is beginning to look fairly familiar, even in this slightly more complicated case &mdash; we have a base case: the least element of a singleton list is its only element; and the least element of a non-singleton list is the least element of its tail unless its head is already the least element of the entire list.</p>
<p>And now we can sort!</p>
<pre class="dontquote prettyprint lang-scala">
trait SelectionSort[L <: HList, S <: HList] {
  def apply(l : L) : S
}

trait LowPrioritySelectionSort {
  implicit def hlistSelectionSort1[S <: HList] = new SelectionSort[S, S] {
    def apply(l : S) : S = l
  }
}

object SelectionSort extends LowPrioritySelectionSort {
  implicit def hlistSelectionSort2[L <: HList, M <: Nat, Rem <: HList, ST <: HList]
    (implicit sl : SelectLeast[L, M, Rem], sr : SelectionSort[Rem, ST]) =
      new SelectionSort[L, M :: ST] {
        def apply(l : L) = {
          val (m, rem) = sl(l)
          m :: sr(rem)
        }
      }
}

def selectionSort[L <: HList, S <: HList](l : L)
  (implicit sort : SelectionSort[L, S]) = sort(l)

val unsorted = _3 :: _1 :: _4 :: _0 :: _2 :: HNil
typed[_3 :: _1 :: _4 :: _0 :: _2 :: HNil](unsorted)
acceptNonDecreasing(unsorted)  // Does not compile!

val sorted = selectionSort(unsorted)
typed[_0 :: _1 :: _2 :: _3 :: _4 :: HNil](sorted)
acceptNonDecreasing(sorted)    // Compiles!
</pre>
<p>As you can see, the static type of the sorted value reflects the fact that it is in sorted order, and that consequently, unlike the initial unsorted value, it has the correct type to be passed to the <span class="prettyprint">acceptNonDecreasing</span> function that we wrote earlier.</p>
<p><b>Update &mdash; Joni Freeman has done a nice job of porting the algorithm used to Prolog <a target="_blank" href="https://gist.github.com/1703501">here</a>.</b></p>
<p>If you've made it this far, and want to play around with it yourself, you can find shapeless on <a target="_blank" href="https://github.com/milessabin/shapeless">github</a> along with the <a target="_blank" href="https://github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/sorting.scala">example source</a> this article is based on. You'll also find a mailing list for discussion around shapeless <a target="_blank" href="https://groups.google.com/forum/#!forum/shapeless-dev">here</a>. Oh, and if you're going to be at Nescala then I'll see you there ...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2012/01/27/type-level-sorting-in-shapeless/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>shapeless at the Northeast Scala Symposium</title>
		<link>http://www.chuusai.com/2012/01/27/shapeless-nescala-2012/</link>
		<comments>http://www.chuusai.com/2012/01/27/shapeless-nescala-2012/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 10:51:29 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Training]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=133</guid>
		<description><![CDATA[I&#8217;ve been selected (against some really excellent competition &#8212; it&#8217;s a shame more talks couldn&#8217;t be squeezed in) to talk at this year&#8217;s Northeast Scala Symposium in Boston. Thanks to everyone who voted for my talk about shapeless. It looks like it&#8217;s going to be a wonderful event, and I&#8217;m really looking forward to meeting<a href="http://www.chuusai.com/2012/01/27/shapeless-nescala-2012/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been selected (against some really excellent competition &mdash; it&#8217;s a shame more talks couldn&#8217;t be squeezed in) to talk at this year&#8217;s <a target="_blank" href="http://nescala.org/">Northeast Scala Symposium</a> in Boston. Thanks to everyone who voted for my <a target="_blank" href="http://nescala.org/#4414303">talk</a> about <a target="_blank" href="https://github.com/milessabin/shapeless">shapeless</a>. It looks like it&#8217;s going to be a wonderful event, and I&#8217;m really looking forward to meeting up with everyone there.</p>
<p>In advance of that, I&#8217;d also be keen to talk to any Scala-using organizations who would be interested in a two/three day <a href="http://www.chuusai.com/scala-training/#advanced-scala">Advanced Scala training course</a> on the East coast in the run up to, or just after the event &mdash; in depth coverage of the techniques involved in the creation of shapeless, and how they can be applied elsewhere, will be included. Please <a href="contact">get in touch</a> if you&#8217;re interested.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2012/01/27/shapeless-nescala-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>shapeless &#8212; an exploration of generic programming in Scala</title>
		<link>http://www.chuusai.com/2011/12/19/shapeless-preview/</link>
		<comments>http://www.chuusai.com/2011/12/19/shapeless-preview/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 15:25:21 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=111</guid>
		<description><![CDATA[shapeless is an exploration of generic (aka polytypic) programming in Scala derived from the various talks I&#8217;ve given over the course of 2011 on implementing scrap your boilerplate and higher rank polymorphism in Scala. It&#8217;s published under the Apache 2.0 licence and hosted on github &#8212; fork it and have a play. In the new<a href="http://www.chuusai.com/2011/12/19/shapeless-preview/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="https://github.com/milessabin/shapeless"><i>shapeless</i></a> is an exploration of generic (aka polytypic) programming in Scala derived from <a target="_blank" href="http://www.chuusai.com/event/skills-matter-fp-exchange/">the</a> <a target="_blank" href="http://www.chuusai.com/event/psug-talk-april/">various</a> <a target="_blank" href="http://www.chuusai.com/event/scala-exchange-skills-matter/">talks</a> I&#8217;ve given over the course of 2011 on implementing <a target="_blank" href="http://goo.gl/KmfVG">scrap your boilerplate</a> and <a target="_blank" href="http://goo.gl/zGRQ7">higher rank polymorphism</a> in Scala. It&#8217;s published under the Apache 2.0 licence and hosted on <a target="_blank" href="https://github.com/milessabin/shapeless">github</a> &mdash; fork it and have a play.</p>
<p>In the new year I&#8217;ll be posting a (long overdue) series of articles here on the implementation techniques used &mdash; heavily type class based, with essential use of dependent types at various junctures, which together enable the relatively smooth encoding of type level functions. In the meantime you&#8217;ll find Olivera, Moors and Odersky <a target="_blank" href="http://goo.gl/ZbcxY"><i>Type Classes as Objects and Implicits</i></a> useful background material.</p>
<p>Selected highlights of shapeless include &#8230;</p>
<ul>
<li>A new encoding of <a target="_blank" href="https://github.com/milessabin/shapeless/blob/master/src/main/scala/shapeless/poly.scala">polymorphic function values</a> which optionally supports type specific cases, and which is interoperable with Scala&#8217;s ordinary monomorphic function values.
<pre class="dontquote prettyprint lang-scala">
// choose is a function from Sets to Options with no type specific cases
object choose extends (Set ~> Option) {
  def default[T](s : Set[T]) = s.headOption
}

// choose is convertible to an ordinary monomorphic function value
val lo = List(Set(1, 3, 5), Set(2, 4, 6)) map choose
lo == List(Option(1), Option(2))

// size is a function from values of arbitrary type to a 'size' which is
// defined via type specific cases
object size extends (Id ~> Const[Int]#λ) {
  def default[T](t : T) = 1
}
implicit def sizeInt = size.λ[Int](x => 1)
implicit def sizeString = size.λ[String](s => s.length)
implicit def sizeList[T] = size.λ[List[T]](l => l.length)
implicit def sizeOption[T](implicit cases : size.λ[T]) =
  size.λ[Option[T]](t => (t map size).getOrElse(0))
implicit def sizeTuple[T, U](implicit st : size.λ[T], su : size.λ[U]) =
  size.λ[(T, U)](t => size(t._1)+size(t._2))

size(23) == 1
size("foo") == 3
size((23, "foo")) == 4
</pre>
</li>
<li>An implementation of <a target="_blank" href="http://goo.gl/pR1OV"><i>Scrap your Boilerplate with Class</i></a> which provides generic map and fold operations over arbitrarily nested data structures,
<pre class="dontquote prettyprint lang-scala">
val nested = List(Option(List(Option(List(Option(23))))))

val succ = everywhere(inc)(nested)
succ == List(Option(List(Option(List(Option(24))))))
</pre>
</li>
<li>A <span class="prettyprint">Typeable</span> type class which provides a <a target="_blank" href="https://github.com/milessabin/shapeless/blob/master/src/main/scala/shapeless/typeable.scala">type safe cast</a> operation,
<pre class="dontquote prettyprint lang-scala">
val a : Any = List(Vector("foo", "bar", "baz"), Vector("wibble"))

val lvs : Option[List[Vector[String]]] = a.cast[List[Vector[String]]]
lvs.isDefined == true

val lvi : Option[List[Vector[Int]]] = a.cast[List[Vector[Int]]]
lvi.isEmpty == true
</pre>
</li>
<li>The mother of all Scala <a target="_blank" href="https://github.com/milessabin/shapeless/blob/master/src/main/scala/shapeless/hlist.scala"><span class="prettyprint">HList</span></a>&#8216;s which, amongst other things, is covariant,
<pre class="dontquote prettyprint lang-scala">
trait Fruit
case class Apple() extends Fruit
case class Pear() extends Fruit

type FFFF = Fruit :: Fruit :: Fruit :: Fruit :: HNil
type APAP = Apple :: Pear :: Apple :: Pear :: HNil

val a : Apple = Apple()
val p : Pear = Pear()

val apap : APAP = a :: p :: a :: p :: HNil
val ffff : FFFF = apap  // APAP <: FFFF
</pre>
<p>It has a map operation, applying a polymorphic function value (possibly with type specific cases) across its elements. This means that it subsumes both typical <span class="prettyprint">HList</span>'s and also <span class="prettyprint">KList</span>'s (<span class="prettyprint">HList</span>'s whose elements share a common outer type constructor),</p>
<pre class="dontquote prettyprint lang-scala">
type SISS = Set[Int] :: Set[String] :: HNil
type OIOS = Option[Int] :: Option[String] :: HNil

val sets : SISS = Set(1) :: Set("foo") :: HNil
val opts : OIOS = sets map choose
opts == Option(1) :: Option("foo") :: HNil
</pre>
<p>It has a <a target="_blank" href="https://github.com/milessabin/shapeless/blob/master/src/main/scala/shapeless/zipper.scala">zipper</a> for traversal and persistent update,</p>
<pre class="dontquote prettyprint lang-scala">
val l = 1 :: "foo" :: 3.0 :: HNil

val l2 = l.toZipper.right.put("wibble", 45).toHList
l2 == 1 :: ("wibble", 45) :: 3.0 :: HNil

val l3 = l.toZipper.right.delete.toHList
l3 == 1 :: 3.0 :: HNil

val l4 = l.toZipper.last.left.insert("bar").toHList
l4 == 1 :: "foo" :: "bar" :: 3.0 :: HNil
</pre>
<p>It has a <span class="prettyprint">unify</span> operation which converts it to an <span class="prettyprint">HList</span> of elements of the least upper bound of the original types,</p>
<pre class="dontquote prettyprint lang-scala">
val ffff = apap.unify // type inferred as FFFF
</pre>
<p>It supports conversion to an ordinary Scala <span class="prettyprint">List</span> of elements of the least upper bound of the original types,</p>
<pre class="dontquote prettyprint lang-scala">
val lf = apap.toList  // type inferred as List[Fruit]
lf == List(a, p, a, p)
</pre>
<p>And it has a <span class="prettyprint">Typeable</span> type class instance, allowing, eg. vanilla <span class="prettyprint">List[Any]</span>'s or <span class="prettyprint">HList</span>'s with elements of type <span class="prettyprint">Any</span> to be safely cast to precisely typed <span class="prettyprint">HList</span>'s,</p>
<pre class="dontquote prettyprint lang-scala">
val ffff : FFFF = apap.unify               // discard precise typing
val apap2 : Option[APAP] = ffff.cast[APAP] // reestablish precise typing
apap2.get == apap
</pre>
<p>These last three features make this <span class="prettyprint">HList</span> dramatically more practically useful than <span class="prettyprint">HList</span>'s are typically thought to be &mdash; normally the full type information required to work with them is too fragile to cross subtyping or I/O boundaries. This implementation supports the discarding of precise information where necessary (eg. to serialize a precisely typed record after construction), and its later reconstruction (eg. a weakly typed deserialized record with a known schema can have it's precise typing reestabilished).</p>
</li>
<li>Conversions between tuples and <span class="prettyprint">HList</span>'s, and between ordinary Scala functions of arbitrary arity and functions which take a single corresponding <span class="prettyprint">HList</span> argument,
<pre class="dontquote prettyprint lang-scala">
// Round trip from tuple to HList and back
val t1 = (23, "foo", 2.0, true)

val l1 = t1.hlisted
h1 == 23 :: "foo" :: 2.0 :: true :: HNil

val t2 = l1.tupled
t1 == t2
</pre>
<p>One application of this is the <a target="_blank" href="https://github.com/milessabin/shapeless/blob/master/src/main/scala/shapeless/lift.scala"><span class="prettyprint">liftO</span></a> function which lifts an ordinary function of arbitrary arity into <span class="prettyprint">Option</span>.</p>
<pre class="dontquote prettyprint lang-scala">
// Lift these ordinary Scala function values into Option
val sum : (Int, Int) => Int = _ + _
val prd : (Int, Int, Int) => Int = _ * _ * _

// Nb. liftO abstracts over the arity of its function arguments
val sumO = liftO(sum) // (Option[Int], Option[Int]) => Option[Int]
val prdO = liftO(prd) // (Option[Int], Option[Int], Option[Int]) => Option[Int]

val s1 = sumO(Some(1), Some(2))
s1 == Option(3)

val s2 = sumO(Some(1), None)
s2 == None

val p1 = prdO(Some(2), Some(3), Some(4))
p1 == Option(24)

val p2 = prdO(Some(2), None, Some(4))
p2 == None
</pre>
</li>
</ul>
<p>The library is targetted at Scala 2.10-SNAPSHOT by default, but currently should build against Scala 2.9.1.final with the <span class="prettyprint">-Ydependent-method-types</span> switch enabled. I make no promises that it'll continue to build with 2.9.x, or even vanilla Scala 2.10-SNAPSHOT &mdash; in 2012 I plan to investigate, amongst other things, what can be done with <a target="_blank" href="http://goo.gl/U18kK">singleton types for literal values</a> &mdash; at a minimum they would make the clunky encoding of type level natural numbers redundant, and might enable a whole lot more.</p>
<p>Fork it, kick the tires over the holiday and let me know how you get on!<br />
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2011/12/19/shapeless-preview/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Functional Dependencies in Scala</title>
		<link>http://www.chuusai.com/2011/07/16/fundeps-in-scala/</link>
		<comments>http://www.chuusai.com/2011/07/16/fundeps-in-scala/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 17:02:24 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=103</guid>
		<description><![CDATA[Functional dependencies are a near-standard extension to Haskell (present in GHC and elsewhere) which allow constraints on the type parameters of type classes to be expressed and then enforced by the compiler. They allow the programmer to state that some of the type parameters of a multi-parameter type class are completely determined by the others.<a href="http://www.chuusai.com/2011/07/16/fundeps-in-scala/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://www.haskell.org/haskellwiki/Functional_dependencies">Functional dependencies</a> are a near-standard extension to  Haskell (present in GHC and elsewhere) which allow constraints on the type parameters of type classes to be expressed and then enforced by the compiler. They allow the programmer to state that some of the type parameters of a multi-parameter type class are completely determined by the others. One particularly common application of this is allowing the result type of a function to be a parameter but nevertheless determined by the type(s) of it&#8217;s argument(s) &mdash; the examples on the Haskell wiki page that I linked to above illustrate that extremely well.</p>
<p>Does this have an equivalent in Scala? We certainly have the equivalent problem &mdash; whenever we have multiple type parameters (of a type or method) we might want to be able to express functional dependency-like constraints between those type parameters and have those constraints checked by the compiler. And ideally we want that to get along well with type-inference &mdash; we would like the compiler to be able to infer any types which are determined by types which it is already able to infer.</p>
<p>It turns out that there&#8217;s a very simple translation of Haskell-style functional dependencies to Scala, but for some reason this doesn&#8217;t seem to have been commented on. Quite the opposite in fact &mdash; I&#8217;ve seen it reported that encoding fundeps in Scala is either impossible, or possible but not useful because of issues with type inference. What makes this even more surprising is that a crucial feature of Scala&#8217;s (now not so) new collections framework (<span class="prettyprint"><a target="_blank" href="http://www.scala-lang.org/api/current/index.html#scala.collection.generic.CanBuildFrom">CanBuildFrom</a></span>) appears to be a perfect example of this encoding in practice &#8230; strangely this isn&#8217;t advertised in <a target="_blank" href="http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf"><i>Type Classes as Objects and Implicits</i></a> (Olivera, Odersky and Moors, 2010) either.</p>
<p>Maybe this has all been noticed before and assumed to be too obvious to mention, nevertheless, I think it&#8217;s useful to be able to make the connection. I&#8217;ll illustrate the translation using the examples from the Haskell wiki. By the time I&#8217;m done translating them into Scala the fact that <span class="prettyprint">CanBuildFrom</span> is an instance of a fundep should be quite clear.</p>
<p>Let&#8217;s start with the matrix/vector/scalar multiplication example. Here we want to express the fact that the result type of the multiplication is fully determined by it&#8217;s arguments,</p>
<div style="padding-left: 30px;">
<table>
<tr>
<td style="text-align: right"><span class="prettyprint">Matrix</span></td>
<td><span class="prettyprint">&nbsp;*&nbsp;</span></td>
<td style="text-align: left"><span class="prettyprint">Matrix</span></td>
<td><span class="prettyprint">&nbsp;-> Matrix</span></td>
</tr>
<tr>
<td style="text-align: right"><span class="prettyprint">Matrix</span></td>
<td><span class="prettyprint">&nbsp;*&nbsp;</span></td>
<td style="text-align: left"><span class="prettyprint">Vector</span></td>
<td><span class="prettyprint">&nbsp;-> Vector</span></td>
</tr>
<tr>
<td style="text-align: right"><span class="prettyprint">Matrix</span></td>
<td><span class="prettyprint">&nbsp;*&nbsp;</span></td>
<td style="text-align: left"><span class="prettyprint">Int</span></td>
<td><span class="prettyprint">&nbsp;-> Matrix</span></td>
</tr>
<tr>
<td style="text-align: right"><span class="prettyprint">Int</span></td>
<td><span class="prettyprint">&nbsp;*&nbsp;</span></td>
<td style="text-align: left"><span class="prettyprint">Matrix</span></td>
<td><span class="prettyprint">&nbsp;-> Matrix</span></td>
</tr>
</table>
</div>
<p>Here we have a triple of types where the first two (the argument types) determine the third (the result type). Lets express this relationship directly via a trait with three type parameters accompanied by some implicit definitions which capture the relationship we want to enforce,</p>
<pre class="dontquote prettyprint lang-scala">
trait Matrix // Dummy definitions for expository purposes
trait Vector

trait MultDep[A, B, C]
// trait MultDep[-A, -B, +C]    // for Scala <= 2.9.0-1 these variance
//                              // annotations are required

implicit object mmm extends MultDep[Matrix, Matrix, Matrix]
implicit object mvv extends MultDep[Matrix, Vector, Vector]
implicit object mim extends MultDep[Matrix, Int, Matrix]
implicit object imm extends MultDep[Int, Matrix, Matrix]
</pre>
<p>Given these definitions we can ask the compiler what is and what isn't allowed,</p>
<pre class="dontquote prettyprint lang-scala">
scala> implicitly[MultDep[Matrix, Matrix, Matrix]] // OK: Matrix * Matrix -> Matrix
res0: MultDep[Matrix,Matrix,Matrix] = mmm$@1ddeda2

scala> implicitly[MultDep[Matrix, Vector, Vector]] // OK: Matrix * Vector -> Vector
res1: MultDep[Matrix,Vector,Vector] = mvv$@1a8fb1b

scala> implicitly[MultDep[Matrix, Vector, Matrix]] // Error
<console>:15: error: could not find implicit value for
  parameter e: MultDep[Matrix,Vector,Matrix]
       implicitly[MultDep[Matrix, Vector, Matrix]]
</pre>
<p>The first two cases are fine, because they both correspond to one of the implicit instances we provided earlier. The third fails, quite rightly, because there is no instance corresponding to <span class="prettyprint">Matrix * Vector -> Matrix</span>.</p>
<p>So, we've been able to capture the desired relationship between the type variables. Here's how we put that to use,</p>
<pre class="dontquote prettyprint lang-scala">
def mult[A, B, C](a : A, b : B)(implicit instance : MultDep[A, B, C]) : C =
  error("TODO")

// Type annotations soley to verify that the correct result type has been inferred
val r1 : Matrix = mult(new Matrix {}, new Matrix{}) // Compiles
val r2 : Vector = mult(new Matrix {}, new Vector{}) // Compiles
val r3 : Matrix = mult(new Matrix {}, 2)            // Compiles
val r4 : Matrix = mult(2, new Matrix {})            // Compiles

// This next one doesn't compile ...
val r5 : Matrix = mult(new Matrix {}, new Vector{})
</pre>
<p>Notice how the third type parameter, <span class="prettyprint">C</span>, isn't used in the first (explicit) parameter list. If it weren't for its appearance in the second (implicit) parameter list the compiler would normally infer it as <span class="prettyprint">Nothing</span> &mdash; not what we want at all. But the combination of type inference and implicit search saves the day. The first two type parameters <span class="prettyprint">A</span> and <span class="prettyprint">B</span> are inferred from the explicit arguments to <span class="prettyprint">mult()</span>, then implicit search kicks in, attempting to locate an implicit definition of <span class="prettyprint">MultDep[_, _, _]</span> consistent with those two types. By construction, it will only ever find one, and that is sufficient to uniquely determine <span class="prettyprint">C</span> for use as the result type of the function.</p>
<p>We have the signature of our <span class="prettyprint">mult()</span> function sorted out, now for the implementation. The (hopefully fairly obvious) trick here is to make our <span class="prettyprint">MultDep</span> instances provide the implementations of the different cases as well as the type constraints,</p>
<pre class="dontquote prettyprint lang-scala">
implicit object mmm extends MultDep[Matrix, Matrix, Matrix] {
  def apply(m1 : Matrix, m2 : Matrix) : Matrix = error("TODO")
}

implicit object mvv extends MultDep[Matrix, Vector, Vector] {
  def apply(m1 : Matrix, v2 : Vector) : Vector = error("TODO")
}

implicit object mim extends MultDep[Matrix, Int, Matrix] {
  def apply(m1 : Matrix, i2 : Int) : Matrix = error("TODO")
}

implicit object imm extends MultDep[Int, Matrix, Matrix] {
  def apply(i1 : Int, m2 : Matrix) : Matrix = error("TODO")
}
</pre>
<p>(filling out the bodies of the dummy <span class="prettyprint">apply()</span> methods is an exercise left for the reader). We can now complete the definition of <span class="prettyprint">mult()</span>,</p>
<pre class="dontquote prettyprint lang-scala">
def mult[A, B, C](a : A, b : B)(implicit instance : MultDep[A, B, C]) : C =
  instance(a, b)
</pre>
<p>And that's all there is to it. The implicit objects correspond exactly to the type class instances in the Haskell original, and the combination of type inference and implicit search captures the functional dependency directly.</p>
<p>Here's the second example from Haskell wiki page, translated in the same way,</p>
<pre class="dontquote prettyprint lang-scala">
trait ExtractDep[A, B] {
  def apply(a : A) : B
}

implicit def ep[A, B] = new ExtractDep[(A, B), A] {
  def apply(p : (A, B)) : A = p._1
}

def extract[A, B](a : A)(implicit instance : ExtractDep[A, B]) : B = instance(a)

// Type annotation soley to verify that the correct result type has been inferred
val c : Char = extract(('x', 3))
</pre>
<p>Of course, neither of these two examples are particularly exciting in Scala as they stand &mdash; Scala has Java-style overloading, which makes the matrix/vector/scalar example mostly redundant; and the second example is a little too artificial to be compelling. Nevertheless, there are many situations where being able to express similar constraints amongst type parameters can be extremely useful &mdash; Scala embedded DSLs often have to deal with situations which are equivalent to wanting a function result type to be determined by its argument types, and I know of a number of DSL designers who've struggled with the problem of unhelpful <span class="prettyprint">Nothing</span>s being inferred for unconstrained result types.</p>
<p>But the best widely known example of a fundep is right under our noses in the Scala standard library itself: <span class="prettyprint"><a target= "_blank" href="http://www.scala-lang.org/api/current/index.html#scala.collection.generic.CanBuildFrom">CanBuildFrom</a></span>. Let's take a look at (a slight simplification of) of the part of its definition which expresses type constraints,</p>
<pre class="dontquote prettyprint lang-scala">
trait CanBuildFrom[From, Elem, To] {
  def apply ...
}
</pre>
<p>Instances of this trait capture collection-type-specific constraints on whether or not a collection of type <span class="prettyprint">To</span> with elements of type <span class="prettyprint">Elem</span> can be created from a collection of type <span class="prettyprint">From</span>. For "regular" collection types (collections which can hold elements of any type) the corresponding instance is equivalent to,</p>
<pre class="dontquote prettyprint lang-scala">
implicit def regularCanBuildFrom[CC[_], A] = new CanBuildFrom[CC[_], A, CC[A]] {
  def apply ...
}
</pre>
<p>In effect this asserts that for a regular collection type it's possible to create a new collection of the same shape, but with an arbitrarily substituted element type. We can ask the compiler about these relationships like so,</p>
<pre class="dontquote prettyprint lang-scala">
scala> import scala.collection.generic._
import scala.collection.generic._

scala> implicitly[CanBuildFrom[List[Int], String, List[String]]]
res0: scala.collection.generic.CanBuildFrom[List[Int],String,List[String]] = ...

scala> implicitly[CanBuildFrom[Set[String], Double, Set[Double]]]
res1: scala.collection.generic.CanBuildFrom[Set[String],Double,Set[Double]] = ...

scala> implicitly[CanBuildFrom[List[String], Int, List[Double]]]
<console>:11: error: Cannot construct a collection of type List[Double] with
  elements of type Int based on a collection of type List[String].
       implicitly[CanBuildFrom[List[String], Int, List[Double]]]
                 ^

scala> implicitly[CanBuildFrom[List[String], Int, Set[Int]]]
<console>:11: error: Cannot construct a collection of type Set[Int] with
  elements of type Int based on a collection of type List[String].
       implicitly[CanBuildFrom[List[String], Int, Set[Int]]]
                 ^
</pre>
<p>As you can see from these examples, the third type argument in <span class="prettyprint">CanBuildFrom</span> is determined by its first two &mdash; it takes its type constructor from the first type argument and its element type from the second type argument. Any attempt to deviate from that pattern results in a static compile time error. This should be sounding familiar ...</p>
<p>Now lets look at where this abstraction is used: the definition of <span class="prettyprint"><a target="_blank" href="http://www.scala-lang.org/api/current/index.html#scala.collection.TraversableLike">TraversibleLike.map()</a></span>,</p>
<pre class="dontquote prettyprint lang-scala">
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
  val b = bf(repr)
  b.sizeHint(this)
  for (x <- this) b += f(x)
  b.result
}
</pre>
<p>It should be apparent that here, like the matrix/vector/scalar example, we have a method with a parametrized result type which is not used in any of its explicit argument types, and hence which can't be inferred from its explicit arguments. Just as in the earlier case, it's the implicit argument which is determining the otherwise unconstrained result type via implicit search for a <span class="prettyprint">CanBuildFrom</span> instance with type parameters <span class="prettyprint">B</span> (determined by type inference from the explicit parameter list) and <span class="prettyprint">Repr</span> (effectively a constant). It should also be apparent that the implicit argument is providing a significant component of the implementation of this method via the call <span class="prettyprint">bf(repr)</span> &mdash; this is exactly analogous to the calls of <span class="prettyprint">instance(a, b)</span> in the earlier example.</p>
<p>Hopefully the discussion above will have persuaded you that these are the hallmarks of a Haskell-like functional dependency, right at the heart of the Scala collections framework. And in my book, that makes fundeps in Scala neither impossible nor useless.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2011/07/16/fundeps-in-scala/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Unboxed union types in Scala via the Curry-Howard isomorphism</title>
		<link>http://www.chuusai.com/2011/06/09/scala-union-types-curry-howard/</link>
		<comments>http://www.chuusai.com/2011/06/09/scala-union-types-curry-howard/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 15:07:18 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=93</guid>
		<description><![CDATA[Update &#8212; I&#8217;ll be giving a talk on this material on the 16th of August in London. Please come along. Scala has a highly expressive type system, but it doesn&#8217;t include everything you might find yourself hankering after &#8212; at least, not as primitives. There are a few genuinely useful things which fall under this<a href="http://www.chuusai.com/2011/06/09/scala-union-types-curry-howard/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p><h5>Update &mdash; I&#8217;ll be giving a talk on this material on the 16th of August in London. <a href="http://www.chuusai.com/2011/06/30/encoding-unboxed-union-types-in-scala-skills-matter/">Please come along</a>.</h5>
<p>Scala has a highly expressive type system, but it doesn&#8217;t include everything you might find yourself hankering after &mdash; at least, not as primitives. There are a few genuinely useful things which fall under this heading &mdash; higher-rank polymorphic function types and recursive structural types are two I&#8217;ll talk about more in later posts. Today I&#8217;m going to show how we can encode union types in Scala, in the course of which I&#8217;ll have an opportunity to shed a little light on the Curry-Howard isomorphism and show how it can be put to work for us.</p>
<p>So, first up, what is a union type? A union type is pretty much what you&#8217;d expect: it&#8217;s the union of two (or more, but I&#8217;ll limit this discussion to just two) types. The values of that type are all of the values of each of the types that it&#8217;s the union of. An example will help to make this clear, but first a little notation &mdash; for reasons which will become apparent later I&#8217;ll write the union of types T and U as T ∨ U (ie. the two types flanking the logical &#8216;or&#8217; operator), and so we write the union of the types Int and String as Int ∨ String. The values of this union type are all the Ints and all the Strings.</p>
<p>What does this mean more concretely? It means that if we could express this type directly in Scala we would be able to write,</p>
<pre class="dontquote prettyprint lang-scala">
def size(x : Int ∨ String) = x match {
  case i : Int => i
  case s : String => s.length
}

size(23) == 23   // OK
size("foo") == 3 // OK
size(1.0)        // Not OK, compile time error
</pre>
<p>In other words, the size method would accept arguments of either type Int or type String (and their subtypes, Null and Nothing) and nothing else.</p>
<p>It&#8217;s important to recognize the difference between this use of a union type and the similar use of Scala&#8217;s standard Either. Either is what&#8217;s known as a sum type, the analog of union types in languages which don&#8217;t support subtyping. Recasting our example in terms of Either we get,</p>
<pre class="prettyprint lang-scala">
def size(x : Either[Int, String]) = x match {
  case Left(i) =&gt; i
  case Right(s) =&gt; s.length
}

size(Left(23)) == 23    // OK
size(Right(&quot;foo&quot;)) == 3 // OK
</pre>
<p>Either[Int, String] can model the union type Int ∨ String because there is an isomorphism between the two types and their values. But equally clearly the Either type manages this by way of a layer of boxed representation, rather then by being an unboxed primitive feature of the type system. Can we do better than Either? Can we find a way of representing union types in Scala which doesn&#8217;t require boxing, and which provides all of the static guarantees we would expect?</p>
<p>It turns out that we can, but to get there we have take a detour through first-order logic via the <a target="_blank" href="http://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence">Curry-Howard isomorphism</a>. Curry-Howard tells us that the relationships between types in a type system can be viewed as an image of the relationships between propositions in a logical system (and vice versa). There are various ways that we can fill that claim out, depending on the type system we&#8217;re talking about and the logical system we&#8217;re working with, but for the purposes of this discussion I&#8217;m going to ignore most of the details and focus on simple examples.</p>
<p>To illustrate Curry-Howard (in the context of a type system with subtyping like Scala&#8217;s), we can see that there is a correspondence between intersection types (A with B in Scala) and logical conjunction (A ∧ B); between my hypothetical union types (A ∨ B) and logical disjunction (also A ∨ B, as hinted earlier); and between subtyping (A <: B in Scala) and logical implication (A ⇒ B). On the left hand side of each row in the table below we have a subtype relationship which is valid in Scala (although, in the case of the union types at the bottom, not directly expressible), and on the right hand side we have a logical formula which is obtained from the type relationship on the left by simply rewriting ("with" to "∧" and "<:" to "⇒") &mdash; in each case the result of the rewriting is a logically valid.</p>
<div style="padding-left: 30px;">
<table>
<tr>
<td style="width: 300px;"><span class="prettyprint">(A with B) <: A</span></td>
<td><span class="prettyprint">(A ∧ B) ⇒ A</span></td>
</tr>
<tr>
<td><span class="prettyprint">(A with B) <: B</span></td>
<td><span class="prettyprint">(A ∧ B) ⇒ B</span></td>
</tr>
<tr>
<td><span class="prettyprint">A <: (A ∨ B)</span></td>
<td><span class="prettyprint">A ⇒ (A ∨ B)</span></td>
</tr>
<tr>
<td><span class="prettyprint">B <: (A ∨ B)</span></td>
<td><span class="prettyprint">B ⇒ (A ∨ B)</span></td>
</tr>
</table>
</div>
<p>The essence of Curry-Howard is that this mechanical rewriting process (whichever direction you go in) will always preserve validity &mdash; valid type formulae will always rewrite to valid logical formulae, and vice versa. This isn&#8217;t only true for conjunction, disjunction and implication. We can also generalize the correspondence to logical formulae which include negation (the key one for us here) and universal and existential quantification.</p>
<p>So what would it mean to add negation to the mix? The conjunction of two types (ie. A with B) has values which are instances of both A and B, so similarly we should expect the negation of a type A (I&#8217;ll write it as ¬[A]) to have as it&#8217;s values everything which <i>isn&#8217;t</i> an instance of A. This is also something which can&#8217;t be directly expressed in Scala, but suppose it was?</p>
<p>If it was, then we would be able to crank on the Curry-Howard isomorphism and <a target="_blank" href="http://en.wikipedia.org/wiki/De_Morgan%27s_laws">De Morgan&#8217;s laws</a> to give us a definition of union types in terms of intersection types (A with B) and type negation. Here&#8217;s how that might go &#8230;</p>
<p>First recall the De Morgan equivalence,</p>
<pre class="dontquote prettyprint lang-scala">
(A ∨ B) ⇔ ¬(¬A ∧ ¬B)
</pre>
<p>Now apply Curry-Howard (using Scala&#8217;s =:= type equality operator),</p>
<pre class="dontquote prettyprint lang-scala">
(A ∨ B) =:= ¬[¬[A] with ¬[B]]
</pre>
<p>If we could work out a way of expressing this in Scala, we&#8217;d be home and dry and have our union types. So can we express type negation?</p>
<p>Unfortunately we can&#8217;t. But what we can do is transform all of our types in a way which allows negation to be expressed in the transformed context. We&#8217;ll then need to work out how make that work for us back in the original untransformed context.</p>
<p>Some readers might have been a little surprised earlier when I illustrated Curry-Howard using intersection types as the correlate of conjunction, union types as the correlate of disjunction and the subtype relation as the correlate of implication. That&#8217;s not how it&#8217;s normally done &mdash; usually product types (ie. (A, B)) model conjunction, sum types (ie. Either[A, B]) model disjunction and function types model implication. If we recast our earlier table in terms of products, sums and functions we end up with this,</p>
<div style="padding-left: 30px;">
<table>
<tr>
<td style="width: 300px;"><span class="prettyprint">(A, B) => A</td>
<td><span class="prettyprint">(A ∧ B) ⇒ A</span></td>
</tr>
<tr>
<td><span class="prettyprint">(A, B) => B</td>
<td><span class="prettyprint">(A ∧ B) ⇒ B</span></td>
</tr>
<tr>
<td><span class="prettyprint">A => Either[A, B]</td>
<td><span class="prettyprint">A ⇒ (A ∨ B)</span></td>
</tr>
<tr>
<td><span class="prettyprint">B => Either[A, B]</td>
<td><span class="prettyprint">B ⇒ (A ∨ B)</span></td>
</tr>
</table>
</div>
<p>On the left hand side we&#8217;re no longer looking for validity with respect to the subtype relation, instead we&#8217;re looking for evidence of the <a target="_blank" href="http://en.wikipedia.org/wiki/Parametricity">principle of parametricity</a>, which allows us to determine if a function type is implementable just by reading it&#8217;s signature. It&#8217;s clear that all the function signatures on the left in the table above can be implemented &mdash; for the first two we have an (A, B) pair as our function argument, so we can easily evalutate to either an A or a B, using _1 or _2,</p>
<pre class="prettyprint lang-scala">
val conj1 : ((A, B)) =&gt; A = p =&gt; p._1
val conj2 : ((A, B)) =&gt; B = p =&gt; p._2
</pre>
<p>and for the last two we have either an A or a B as our function argument, so we can evalute to Either[A, B] (as Left[A] or Right[B] respectively).</p>
<pre class="prettyprint lang-scala">
val disj1 : A =&gt; Either[A, B] = a =&gt; Left(a)
val disj2 : B =&gt; Either[A, B] = b =&gt; Right(b)
</pre>
<p>This is the form in which the Curry-Howard isomorphism is typically expressed for languages without subtyping. Because this mapping doesn&#8217;t reflect subtype relations it isn&#8217;t going to be much direct use to us for expressing union types which, like intersection types, are inherently characterized in terms of subtyping. But it can help us out with negation, which is the missing piece that we need.</p>
<p>Either with or without subtyping, the bottom type (Scala&#8217;s Nothing type) maps to logical falsehood, so for example, the following equivalences all hold,</p>
<div style="padding-left: 30px;">
<table>
<tr>
<td style="width: 300px;"><span class="prettyprint">A => Either[A, Nothing]</td>
<td><span class="prettyprint">A ⇒ (A ∨ false)</span></td>
</tr>
<tr>
<td><span class="prettyprint">B => Either[Nothing, B]</td>
<td><span class="prettyprint">B ⇒ (false ∨ B)</span></td>
</tr>
</table>
</div>
<p>because the function signatures on the left are once again all implementable, and the logical formulae on the right are again all valid (see this <a target="_blank" href="http://james-iry.blogspot.com/2011/05/why-eager-languages-dont-have-products.html">post</a> from James Iry for an explanation of why I haven&#8217;t shown the corresponding cases for products/conjunctions). Now we need to think about what a function signature like,</p>
<pre class="prettyprint lang-scala">
A =&gt; Nothing
</pre>
<p>corresponds to. On the logical side of Curry-Howard this maps to A ⇒ false, which is equivalent to ¬A. This seems fairly intuitively reasonable &mdash; there are no values of type Nothing, so the signature A => Nothing can&#8217;t be implemented (other than by throwing an exception, which isn&#8217;t allowed).</p>
<p>Let&#8217;s see what happens if we take this as our representation of the negation of a type,</p>
<pre class="dontquote prettyprint lang-scala">
type ¬[A] = A => Nothing
</pre>
<p>and apply it back in the subtyping context that we started with to see if we can now use De Morgan&#8217;s laws to get the union types we&#8217;re after,</p>
<pre class="dontquote prettyprint lang-scala">
type ∨[T, U] = ¬[¬[T] with ¬[U]]
</pre>
<p>We can test this using the Scala REPL, which will very quickly show us that we&#8217;re not quite there yet,</p>
<pre class="dontquote prettyprint lang-scala">
scala> type ¬[A] = A => Nothing
defined type alias $u00AC

scala> type ∨[T, U] = ¬[¬[T] with ¬[U]]
defined type alias $u2228

scala> implicitly[Int &lt;:&lt; (Int ∨ String)]
&lt;console>:11: error: Cannot prove that Int &lt;:&lt;
  ((Int) => Nothing with (String) => Nothing) => Nothing.
       implicitly[Int &lt;:&lt; (Int ∨ String)]
</pre>
<p>The expression &#8220;implicitly[Int <:< (Int ∨ String)]&#8221; is asking the compiler if it can prove that Int is a subtype of Int ∨ String, which it would be if we had succeeded in coming up with an encoding of union types.</p>
<p>So what&#8217;s gone wrong? The problem is that we have transformed the types on the right hand side of the <:< operator into function types so that we can make use of the encoding of type negation as A => Nothing. This means that the union type is itself a function type. That&#8217;s clearly not consistent with Int being a subtype of it &mdash; as the error message from the REPL shows. To make this work, then, we also need to transform the left hand side of the <:< operator into a type which could possibly be a subtype of the type on the right. What could that transformation be? How about double negation?</p>
<pre class="dontquote prettyprint lang-scala">
type ¬¬[A] = ¬[¬[A]]
</pre>
<p>Lets see what the compiler says now,</p>
<pre class="dontquote prettyprint lang-scala">
scala> type ¬¬[A] = ¬[¬[A]]
defined type alias $u00AC$u00AC

scala> implicitly[¬¬[Int] &lt;:&lt; (Int ∨ String)]
res5: &lt;:&lt;[((Int) => Nothing) => Nothing,
  ((Int) => Nothing with (String) => Nothing) => Nothing] = &lt;function1>

scala> implicitly[¬¬[String] &lt;:&lt; (Int ∨ String)]
res6: &lt;:&lt;[((String) => Nothing) => Nothing,
  ((Int) => Nothing with (String) => Nothing) => Nothing] = &lt;function1>
</pre>
<p>Bingo! ¬¬[Int] and ¬¬[String] are both now subtypes of Int ∨ String!</p>
<p>Let's just check that this isn't succeeding vacuously,</p>
<pre class="dontquote prettyprint lang-scala">
scala> implicitly[¬¬[Double] &lt;:&lt; (Int ∨ String)]
&lt;console>:12: error: Cannot prove that ((Double) => Nothing) => Nothing &lt;:&lt;
  ((Int) => Nothing with (String) => Nothing) => Nothing.
       implicitly[¬¬[Double] &lt;:&lt; (Int ∨ String)]
</pre>
<p>We're almost there, but there's one remaining loose end to tie up &mdash; we have subtype relationships which are isomorphic to the ones we want (because ¬¬[T] is isomorphic to T), but we don't yet have a way to express those relationships with respect to the the untransformed types that we really want to work with.</p>
<p>We can do that by treating our ¬[T], ¬¬[T] and (T ∨ U) as phantom types, using them only to represent the subtype relationships on the underlying type rather that working directly with their values. Here's how that goes for our motivating example,</p>
<pre class="dontquote prettyprint lang-scala">
def size[T](t : T)(implicit ev : (¬¬[T] &lt;:&lt; (Int ∨ String))) = t match {
  case i : Int => i
  case s : String => s.length
}
</pre>
<p>This is using a generalized type constraint to require the compiler to be able to prove that any T inferred as the argument type of the size method must be such that it's double negation is a subtype of (Int ∨ String). That's only ever true when T is Int or T is String, as this REPL session shows,</p>
<pre class="dontquote prettyprint lang-scala">
scala> def size[T](t : T)(implicit ev : (¬¬[T] &lt;:&lt; (Int ∨ String))) = t match {
     |     case i : Int => i
     |     case s : String => s.length
     |   }
size: [T](t: T)(implicit ev: &lt;:&lt;[((T) => Nothing) => Nothing,
  ((Int) => Nothing with (String) => Nothing) => Nothing])Int

scala> size(23)
res8: Int = 23

scala> size("foo")
res9: Int = 3

scala> size(1.0)
<console>:13: error: Cannot prove that ((Double) => Nothing) => Nothing &lt;:&lt;
  ((Int) => Nothing with (String) => Nothing) => Nothing.
       size(1.0)
</pre>
<p>One last little trick to finesse this slightly. The implicit evidence parameter is syntactically a bit ugly and heavyweight, and we can improve things a little by converting it to a context bound on the type parameter T like so,</p>
<pre class="dontquote prettyprint lang-scala">
type |∨|[T, U] = { type λ[X] = ¬¬[X] <:< (T ∨ U) }

def size[T : (Int |∨| String)#λ](t : T) = t match {
    case i : Int => i
    case s : String => s.length
}
</pre>
<p>And there you have it &mdash; an unboxed, statically type safe encoding of union types in unmodified Scala!</p>
<p>Obviously it would be nicer if Scala supported union types as primitives, but at least this construction shows that the Scala compiler has all the information it needs to be able to do that. Now we just need to pester Martin and Adriaan to make it directly accessible.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2011/06/09/scala-union-types-curry-howard/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
		<item>
		<title>Chuusai becomes the first Scala Fly Space Partner</title>
		<link>http://www.chuusai.com/2011/06/03/chuusai-fly-space-partnership/</link>
		<comments>http://www.chuusai.com/2011/06/03/chuusai-fly-space-partnership/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 12:40:25 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=90</guid>
		<description><![CDATA[Today Chuusai and Zink Digital announced an agreement for Chuusai to become a Fly Space consulting and training partner. The agreement means that Chuusai will offer both integration assistance for Fly customers using the Scala interface, and provide training and support to ensure that projects using Fly and Scala get the most from this powerful<a href="http://www.chuusai.com/2011/06/03/chuusai-fly-space-partnership/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>Today <a href="http://www.chuusai.com/">Chuusai</a> and <a target="_blank" href="http://www.flyobjectspace.com/">Zink Digital</a> announced an agreement for Chuusai to become a Fly Space consulting and training partner. The agreement means that Chuusai will offer both integration assistance for Fly customers using the Scala interface, and provide training and support to ensure that projects using Fly and Scala get the most from this powerful new combination of technologies.</p>
<p>Nigel Warren, designer of Fly, said &#8220;I&#8217;m delighted that Miles and his team at Chuusai will be bringing all of their deep understanding of Scala in the High Performance, Financial and Scientific Computing domains to bear on projects using Fly to cluster their distributed Scala apps. The Fly team has worked very hard to make the Scala interface natural for Scala developers by, for example, including direct support for Actors, whilst maximising performance by writing native Scala objects directly to the Fly server.&#8221;</p>
<p>Miles Sabin of Chuusai said &#8220;We&#8217;re delighted to be working with the Fly team to bring the combination of tuple spaces and Scala to a wider audience. Tuple spaces are coming into their own in our new environment of ubiquitous parallelism and distribution, and Fly, being the foremost implementation available on the Java Virtual Machine, and the only one with a Scala interface, deserves serious attention from everyone working in demanding computational domains.&#8221;</p>
<div class="pr-contact">Contact Miles Sabin, <a href="mailto:miles.sabin@chuusai.com">miles.sabin@chuusai.com</a>, +44 1273 319 080, for Chuusai</div>
<div class="pr-contact">Contact Nigel Warren, <a href="mailto:nige@zink-digital.com">nige@zink-digital.com</a>, for Zink Digital</div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2011/06/03/chuusai-fly-space-partnership/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from SPA 2010 Scala Workshop available</title>
		<link>http://www.chuusai.com/2010/05/20/spa-workshop-slides/</link>
		<comments>http://www.chuusai.com/2010/05/20/spa-workshop-slides/#comments</comments>
		<pubDate>Thu, 20 May 2010 23:28:22 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=28</guid>
		<description><![CDATA[BCS SPA 2010 &#8211; An Introduction to Scala for Java Developers]]></description>
			<content:encoded><![CDATA[<div id="__ss_7036968">
<p><a href="http://www.slideshare.net/milessabin/bcs-spa-2010-an-introduction-to-scala-for-java-developers" title="BCS SPA 2010 - An Introduction to Scala for Java Developers">BCS SPA 2010 &#8211; An Introduction to Scala for Java Developers</a></p>
<p> <object id="__sse7036968" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=spa-20100518-110223173037-phpapp02&#038;stripped_title=bcs-spa-2010-an-introduction-to-scala-for-java-developers&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse7036968" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=spa-20100518-110223173037-phpapp02&#038;stripped_title=bcs-spa-2010-an-introduction-to-scala-for-java-developers&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2010/05/20/spa-workshop-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from Scala Days 2010 available</title>
		<link>http://www.chuusai.com/2010/04/17/scala-days-slides/</link>
		<comments>http://www.chuusai.com/2010/04/17/scala-days-slides/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 23:16:32 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=27</guid>
		<description><![CDATA[Scaladays 2010 &#8211; The Scala IDE for Eclipse &#8211; Retrospect and Prospect for 2.8 and Beyond]]></description>
			<content:encoded><![CDATA[<div id="__ss_7036915">
<p><a href="http://www.slideshare.net/milessabin/scaladays-2010-the-scala-ide-for-eclipse-retrospect-and-prospect-for-28-and-beyond" title="Scaladays 2010 - The Scala IDE for Eclipse - Retrospect and Prospect for 2.8 and Beyond">Scaladays 2010 &#8211; The Scala IDE for Eclipse &#8211; Retrospect and Prospect for 2.8 and Beyond</a></p>
<p> <object id="__sse7036915" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=scaladays-20100416-110223172306-phpapp01&#038;stripped_title=scaladays-2010-the-scala-ide-for-eclipse-retrospect-and-prospect-for-28-and-beyond&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse7036915" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=scaladays-20100416-110223172306-phpapp01&#038;stripped_title=scaladays-2010-the-scala-ide-for-eclipse-retrospect-and-prospect-for-28-and-beyond&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object> </div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2010/04/17/scala-days-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from Eclipsecon 2010 session available</title>
		<link>http://www.chuusai.com/2010/03/26/eclipsecon-slides/</link>
		<comments>http://www.chuusai.com/2010/03/26/eclipsecon-slides/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 23:03:44 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=26</guid>
		<description><![CDATA[Eclipsecon 2010 &#8211; Scala Support in Eclipse]]></description>
			<content:encoded><![CDATA[<div id="__ss_7036779">
<p><a href="http://www.slideshare.net/milessabin/eclipsecon-2010-scala-support-in-eclipse" title="Eclipsecon 2010 - Scala Support in Eclipse">Eclipsecon 2010 &#8211; Scala Support in Eclipse</a></p>
<p> <object id="__sse7036779" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=eclipsecon-20100325-110223170716-phpapp02&#038;stripped_title=eclipsecon-2010-scala-support-in-eclipse&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse7036779" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=eclipsecon-20100325-110223170716-phpapp02&#038;stripped_title=eclipsecon-2010-scala-support-in-eclipse&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object> </div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2010/03/26/eclipsecon-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from Scala briefing at BNP Paribas available</title>
		<link>http://www.chuusai.com/2010/02/26/bnp-paribas-slides/</link>
		<comments>http://www.chuusai.com/2010/02/26/bnp-paribas-slides/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 19:23:13 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=25</guid>
		<description><![CDATA[An Introduction to Scala &#8211; Blending OO and Functional Paradigms]]></description>
			<content:encoded><![CDATA[<div id="__ss_7034473">
<p><a href="http://www.slideshare.net/milessabin/an-introduction-to-scala" title="An Introduction to Scala - Blending OO and Functional Paradigms">An Introduction to Scala &#8211; Blending OO and Functional Paradigms</a></p>
<p> <object id="__sse7034473" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=bnp-20100225-110223132600-phpapp01&#038;stripped_title=an-introduction-to-scala&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse7034473" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=bnp-20100225-110223132600-phpapp01&#038;stripped_title=an-introduction-to-scala&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object> </div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2010/02/26/bnp-paribas-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from Scala presentation at Skillsmatter available</title>
		<link>http://www.chuusai.com/2010/01/29/intro-to-scala-slides/</link>
		<comments>http://www.chuusai.com/2010/01/29/intro-to-scala-slides/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 19:11:41 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=24</guid>
		<description><![CDATA[An Introduction to Scala for Java Developers]]></description>
			<content:encoded><![CDATA[<div id="__ss_4148017">
<p><a href="http://www.slideshare.net/milessabin/spa-20100518" title="An Introduction to Scala for Java Developers">An Introduction to Scala for Java Developers</a></p>
<p> <object id="__sse4148017" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=spa-20100518-100519020442-phpapp01&#038;stripped_title=spa-20100518&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse4148017" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=spa-20100518-100519020442-phpapp01&#038;stripped_title=spa-20100518&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2010/01/29/intro-to-scala-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala and the Scala IDE for Eclipse 2.8 Beta 1 released</title>
		<link>http://www.chuusai.com/2010/01/27/scala-ide-2-8-beta-1-released/</link>
		<comments>http://www.chuusai.com/2010/01/27/scala-ide-2-8-beta-1-released/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 19:08:28 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=23</guid>
		<description><![CDATA[Read the full announcement here.]]></description>
			<content:encoded><![CDATA[<p>Read the full announcement <a href="http://www.scala-lang.org/node/4587" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2010/01/27/scala-ide-2-8-beta-1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from Eclipse DemoCamp London available</title>
		<link>http://www.chuusai.com/2009/11/25/eclipse-democamp-london-slides/</link>
		<comments>http://www.chuusai.com/2009/11/25/eclipse-democamp-london-slides/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 18:59:25 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=22</guid>
		<description><![CDATA[Scala Support in Eclipse &#8211; Monkey-patching the JDT for fun and profit?]]></description>
			<content:encoded><![CDATA[<div id="__ss_3083333">
<p><a href="http://www.slideshare.net/milessabin/scala-support-in-eclipse-monkeypatching-the-jdt-for-fun-and-profit" title="Scala Support in Eclipse - Monkey-patching the JDT for fun and profit?">Scala Support in Eclipse &#8211; Monkey-patching the JDT for fun and profit?</a></p>
<p> <object id="__sse3083333" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=eclipsedemocamp-20091124-100205152157-phpapp01&#038;stripped_title=scala-support-in-eclipse-monkeypatching-the-jdt-for-fun-and-profit&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse3083333" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=eclipsedemocamp-20091124-100205152157-phpapp01&#038;stripped_title=scala-support-in-eclipse-monkeypatching-the-jdt-for-fun-and-profit&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object> </div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2009/11/25/eclipse-democamp-london-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Miles Sabin interviewed by 51CTO.com</title>
		<link>http://www.chuusai.com/2009/11/20/51cto-interview/</link>
		<comments>http://www.chuusai.com/2009/11/20/51cto-interview/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 18:56:23 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=20</guid>
		<description><![CDATA[Read the full article here.]]></description>
			<content:encoded><![CDATA[<p>Read the full article <a href="http://developer.51cto.com/art/200911/164190.htm" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2009/11/20/51cto-interview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala and the Scala IDE for Eclipse 2.7.7 released</title>
		<link>http://www.chuusai.com/2009/10/28/scala-ide-2-7-7-released/</link>
		<comments>http://www.chuusai.com/2009/10/28/scala-ide-2-7-7-released/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 18:39:41 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=18</guid>
		<description><![CDATA[Read the full annoucement here.]]></description>
			<content:encoded><![CDATA[<p>Read the full annoucement <a href="http://www.scala-lang.org/node/3906" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2009/10/28/scala-ide-2-7-7-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from the JVM Languages Summit available</title>
		<link>http://www.chuusai.com/2009/09/27/jvm-lang-summit-slides/</link>
		<comments>http://www.chuusai.com/2009/09/27/jvm-lang-summit-slides/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 18:35:09 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=17</guid>
		<description><![CDATA[JVM Languages Support in Eclipse &#8211; Monkey-patching the JDT for fun and profit?]]></description>
			<content:encoded><![CDATA[<div id="__ss_3083330">
<p><a href="http://www.slideshare.net/milessabin/jvm-languages-support-in-eclipse-monkeypatching-the-jdt-for-fun-and-profit" title="JVM Languages Support in Eclipse - Monkey-patching the JDT for fun and profit?">JVM Languages Support in Eclipse &#8211; Monkey-patching the JDT for fun and profit?</a></p>
<p> <object id="__sse3083330" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jvmlangsummit-20090916-100205152142-phpapp01&#038;stripped_title=jvm-languages-support-in-eclipse-monkeypatching-the-jdt-for-fun-and-profit&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse3083330" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jvmlangsummit-20090916-100205152142-phpapp01&#038;stripped_title=jvm-languages-support-in-eclipse-monkeypatching-the-jdt-for-fun-and-profit&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2009/09/27/jvm-lang-summit-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from 15th Sept BASE presentation available</title>
		<link>http://www.chuusai.com/2009/09/27/base-slides/</link>
		<comments>http://www.chuusai.com/2009/09/27/base-slides/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 13:02:44 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=15</guid>
		<description><![CDATA[The Scala IDE for Eclipse &#8211; Retrospect and Prospect for 2.8.0]]></description>
			<content:encoded><![CDATA[<div id="__ss_3083329">
<p><a href="http://www.slideshare.net/milessabin/the-scala-ide-for-eclipse-retrospect-and-prospect-for-280" title="The Scala IDE for Eclipse - Retrospect and Prospect for 2.8.0">The Scala IDE for Eclipse &#8211; Retrospect and Prospect for 2.8.0</a></p>
<p><object id="__sse3083329" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=base-20090915-100205152136-phpapp02&#038;stripped_title=the-scala-ide-for-eclipse-retrospect-and-prospect-for-280&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse3083329" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=base-20090915-100205152136-phpapp02&#038;stripped_title=the-scala-ide-for-eclipse-retrospect-and-prospect-for-280&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2009/09/27/base-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala and the Scala IDE for Eclipse 2.7.6 released</title>
		<link>http://www.chuusai.com/2009/09/10/scala-ide-2-7-6-released/</link>
		<comments>http://www.chuusai.com/2009/09/10/scala-ide-2-7-6-released/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 12:59:02 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=14</guid>
		<description><![CDATA[Read the full announcement here.]]></description>
			<content:encoded><![CDATA[<p>Read the full announcement <a href="http://www.scala-lang.org/node/3250" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2009/09/10/scala-ide-2-7-6-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides from 2nd July LSUG presentation available</title>
		<link>http://www.chuusai.com/2009/07/09/lsug-slides/</link>
		<comments>http://www.chuusai.com/2009/07/09/lsug-slides/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 12:52:06 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=13</guid>
		<description><![CDATA[What&#39;s new in Scala and the Scala IDE for Eclipse for 2.8.0]]></description>
			<content:encoded><![CDATA[<div id="__ss_3083331">
<p><a href="http://www.slideshare.net/milessabin/whats-new-in-scala-and-the-scala-ide-for-eclipse-for-280" title="What&#39;s new in Scala and the Scala IDE for Eclipse for 2.8.0">What&#39;s new in Scala and the Scala IDE for Eclipse for 2.8.0</a></p>
<p><object id="__sse3083331" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=lsug-20090702-100205152154-phpapp01&#038;stripped_title=whats-new-in-scala-and-the-scala-ide-for-eclipse-for-280&#038;userName=milessabin" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse3083331" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=lsug-20090702-100205152154-phpapp01&#038;stripped_title=whats-new-in-scala-and-the-scala-ide-for-eclipse-for-280&#038;userName=milessabin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2009/07/09/lsug-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Miles Sabin interviewed by scala-lang.org</title>
		<link>http://www.chuusai.com/2009/06/08/scala-lang-org-interview/</link>
		<comments>http://www.chuusai.com/2009/06/08/scala-lang-org-interview/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 12:40:53 +0000</pubDate>
		<dc:creator>Miles Sabin</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.chuusai.com/?p=11</guid>
		<description><![CDATA[Read the full article here.]]></description>
			<content:encoded><![CDATA[<p>Read the full article <a href="http://www.scala-lang.org/node/2119" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chuusai.com/2009/06/08/scala-lang-org-interview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.639 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-21 05:15:04 -->
<!-- Compression = gzip -->
