Showing posts with label language. Show all posts
Showing posts with label language. Show all posts

Friday, January 8, 2010

Why do I love APL?

I love the strangest languages for various reasons. Some of them have immense power, but can easily produce unmaintainable messes. Some have the elegant simplicity of zen, but never attracted the people who build kitchen sinks. Some are perfect matches for certain applications, and quickly degenerate for other usages.

In Scala I have found for the first time a positive combination of these attributes. Immense power, kitchen sinks, check. Simplicity? Perhaps not, but more so than the more popular alternatives. Some code has definitely a zen-like quality to it. And, yet, it is of general use, and has good enough resilience against unmaintainable messes. Not perfect, but better than anything else I know of, for now.

That doesn't mean I do not appreciate other languages. There is much to learn and admire in many, many languages, and I would not mind using quite a few of them if chance favors it.

So I'll leave you with the answer that came to my mind as I explained to a bewildered person why I loved APL -- a language I could spend a whole afternoon producing half a line of code:

There's joy to be found in writing code which is solely about what you want, and not about how to get there. Of expressing the fulness of your intent as a single expression. It's like the ultimate perfect katana cut.

Of course, in a real fight I'd rather have a gun.

Wednesday, June 24, 2009

Matrices 2

I’ll continue today with a little series for beginners. On my first post I forgot something important. One of the very first things I do with a class is create a toString method. This way, I get instant feedback on how my class is doing, as I paste it into the REPL, and try out the methods I defined.

So, let’s think of a toString method. Since all data in my class is stored in the private val “self”, we could simply delegate the task of producing a string:


override def toString = self.toString


That might do at first, but it would be unreasonable to expect something better formatted than that. First, let’s see if we can’t get the output in multiple lines, using mkString:


override def toString = self mkString “\n”


Unfortunately, the output of that looks like this:


res6: String =
[I@196a753
[I@1c36f46


This wouldn’t happen with a List, but an Array is implemented to be compatible with Java, and Java had Arrays have some intrinsic limitations, as they were present in the language from the very beginning, much before generics, and some design decisions about them proved to be unfortunate. Anyway, let’s fix that:


override def toString = self map (_ mkString “ “) mkString “\n”


Better, but we can improve on that still. For one thing, it would be much better if the columns were aligned. Now, to align the columns, we first must know how big a column can get. Or, in other words, we must know the size of the number with the biggest string representation in the matrix.

So, summing it up, we have to look through all of the matrix elements, get their sizes, and choose the biggest one. Getting a number’s size is easy: number.toString.size. Now, if we had a list, this would be easy, but we have an array of arrays. When we have nested collections and we want to unnest them, we use flatMap. For instance:


scala> Array(Array(15,0),Array(2,-30)) flatMap (x => x)
res19: Array[Int] = Array(15, 0, 2, -30)


The flatMap operation we used, (x => x), simply returns what it was given. If all you want is unnest the collections, this suffices. But, actually, we want the number sizes. Since “x” is an Array, not a number, we can’t do flatMap (x => x.toString.size). But we can replace the numbers with their sizes, and then unnest the arrays, like this:


scala> Array(Array(15,0),Array(2,-30)) flatMap (_ map (_.toString.size))
res20: Array[Int] = Array(2, 1, 1, 3)


Next, we want to get the biggest one. We have a collection of number sizes, and we want to reduce it to the single biggest one. We have two such methods in Scala: reduceLeft and reduceRight. Since “max” is commutative, both will produce the same result. But reduceLeft has a better performance, as it iterates over the collection in the order given. The final code should look like this, then:


val maxNumSize = self flatMap (_ map (_.toString.size)) reduceLeft (_ max _)


Pretty easy, eh? My first version had three lines, and was much more confusing to read. It helps stating what your problem is – you’ll often see you can do exactly that in Scala. So, we have a size, what do we do with it? Well, let’s just make sure all numbers are printed to that size. If we format them with “%2d”, for instance, every number will take at least two characters, with the left side being filled with a space as needed. To produce such formatted numbers, we’ll make use of RichString’s “format” method:


override def toString = {
val maxNumSize = self.projection flatMap (_ map (_.toString.size)) reduceLeft (_ max _)
val numFormat = "%"+maxNumSize+"d"
self map (_ map (numFormat format _) mkString “ “) mkString “\n”
}


That’s it! I added a “projection” there to make it a bit more performatic, as it doesn’t produce intermediate arrays. On Scala 2.8, that method gets replaced with “view”, with “projection” remaining as deprecated. Well, that was so easy I want to do more. First, I want to produce little vertical bars on the sides, to make clear the matrix boundaries, in case we are printing them side by side. That just requires changing the inner mkString to mkString(“| “, “ “, “ |”). But I also want to bend the bars up and down, to indicate the top and bottom lines, as well as produce something special for one-line matrices.

For all of them, we are just making small changes in the inner mkString. We have one for the top line, one for the intermediate ones, and one for the bottom line. We could make a list of all these lines, and then use mkString on the list, but we have to be careful, because the “bottom” line and the “intermediate” lines might not exist, and the top line has two different formats depending on whether the matrix has more than one line or not. Taking that into account, here is a much larger, but, hopefully, nicer toString method:


override def toString = {
val maxNumSize = self.projection flatMap (_ map (_.toString.size)) reduceLeft (_ max _)
val numFormat = "%"+maxNumSize+"d"
def formatNumber(n: Int) = numFormat format n
val top = rows match {
case 1 => _row(0) map formatNumber mkString ("< ", " ", " >")
case _ => _row(0) map formatNumber mkString ("/ ", " ", " \\")
}
val middle = rows match {
case 1 | 2 => Nil
case _ => self.toList.tail.init map (_ map formatNumber mkString("| "," "," |"))
}
val bottom = rows match {
case 1 => Nil
case _ => List(_row(rows - 1) map formatNumber mkString ("\\ ", " ", " /"))
}

top :: middle ::: bottom mkString "\n"
}


In a parting note, someone suggested one technique to be able to parametrize the class. There are many, but they are slower than using "AnyVal" types directly. If I happen to be mistaken, please do post about it at length!

Tuesday, June 23, 2009

Matrices and Fibonacci 1

When I was beginning to learn Scala, I decided one of my projects would be rewrite this stuff in Scala. The idea behind that is to compute Fibonacci Numbers using matrices. I won’t bother describing how it is done, as this is well covered on both of those links. Suffice to say that I need to computer the nth power of a 2x2 matrix of integers. This project was all but forgotten for a long time…

So it happened that just yesterday I was cleaning my to-do list, and I came upon that. I took a second look into it, and decided to take the plunge. Now, Raganwald uses an optimization which enables him to do the operations on vectors, but, by now, I actually thought the whole exercise was trivial and pointless.

I took a brief look into matrix libraries for Scala. I found the Scalala (as in Scala Linear Algebra) library, which does everything I need, very efficiently at that. My problem would be reduced to something like this (untested):


def fib(n) = n match {
case 0 => throw new IllegalArgumentException
case 1 => 1
case _ =>
val m = DenseMatrix(2,2)(1); m(1,1) = 0
val mPowered = m :^ n
mPowered(0,1)
}


Boring, wasn’t it? Yeah, I thought so too. Instead, I decided to write my own Matrix library. Pretty trivial stuff, but at least I’d take something out of it, I thought. So, I’ll talk about that: writing my Matrix library. If that will bore you, you might as well stop right here. I’ll show, though, some of the design decisions and constrains I faced. For someone new to Scala, it might be interesting read.

Well, then, where to start? With a class, of course. Ideally, I’d like to write something like this:


class Matrix[T]


This way, I could use matrices of Double for most use cases, of Ints or Longs for things like the Fibonacci problem, and BigDecimal for tough stuff. Unfortunately, we can’t do that. We need access to operators such as +, - and * over type T, and that means I need an upper bound for T defining these operators. Unfortunately, these types do not share an interface defining those elements. You see, they are not really “classes” as far as Java is concerned, and not being a proper class, they can’t share an abstract class or interface with these methods. Well, BigDecimal is a class, alright, but that’s it.

Because of this, I decided, instead, to define my class as MatrixInt. This was enough for Fibonacci, but later I created a MatrixDouble as well, just to finish implementing the most basic methods such a class would need.

There is a way around that. I can get away with a structural type, but that would be so slow as to defeat the whole purpose of a Matrix class. So I’ll skip it altogether.

The next design decision is how to store my data, and what constructor to use. Generally speaking, there are two strategies for storing a matrix: as a dense matrix or as a sparse matrix. A dense matrix is simply stored as an addressable, fixed-size, contiguously allocated buffer. Or, in other words, an array. A sparse matrix is used for matrices that are very large in their dimensions, but are mostly populated with zeros. Performance can go either way, depending on what kind of data and algorithms you are using those matrices for. For Fibonacci, dense is the way to go. Since it is also the easier way to go, I chose that way.

We also need to know how many dimensions the matrices may have. For simplicity sake, I chose bi-dimensional matrices, and that’s it. With all that in mind, my class thus began:


class MatrixInt(array: Array[Array[Int]]) {


I decided to take an array of proper dimensions as my constructor, instead of providing something special myself. With Scala 2.8, you can pass Array.ofDim(2,2) and be done with it. We’ll see something similar further down too.

Now, one important thing to consider is that an Array is a mutable object. I have decided to make my matrices immutable, so that I could use them just like I use Ints or Doubles. But, to ensure that is true, I can’t really on the array passed with the constructor, as it might change. So, first thing I do is copy it. Here:


private def clone(a: Array[Array[Int]]) =
for((i: Int) <- (0 until a.size).toArray)
yield for((j: Int) <- (0 until a(0).size).toArray)
yield a(i)(j)

private val self = clone(array)


This clone array method will help in places other than the constructor. For instance, if the user wants the Array representation of the matrix, I have to clone my internal representation before passing it on. But there are more interesting things about it. Let’s consider it…

One thing to notice about it, is that instead of having a single for/yield statement, I have two, the second being fed to the first’s yield. It is built this way because I want to create an Array of Arrays. Each yield will result in one collection. Two collections, two yield statements.

Then we have ranges: (0 until a.size) and (0 until a(0).size). A statement like (0 until 5) will produce a range which, when iterated over, will yield 0, 1, 2, 3 and 4. It can do a few other things too, but let’s not be bothered by them. Note that if you want an “inclusive”, range, one which will include the upper limit (5, in the example), you use “to” instead of “until”. Or you create a new range from the existing one with “inclusive”.

Next, “.toArray”. Though a range will do as far as generating indices, I want yield to return an Array. If you want yield to return collection X, pass a collection X to the for statement. Therefore, “.toArray” to convert the range into an array.

The final thing to consider is the last yield statement. Yield a(i)(j). As I started writing my methods, I got very similar patterns, with only the last yield changing. So I started to consider how to reuse that code. The thing to consider, here, is that the intent of this double for/yield pattern is to create an array of arrays of the proper size, and populate it with a function of my choosing. Thinking about it that way, a refactoring might be done as follow:


protected def createArrays(rows: Int, cols: Int, f: (Int, Int) => Int) =
for((i: Int) <- (0 until rows).toArray)
yield for((j: Int) <- (0 until cols).toArray)
yield f(i,j)

protected def clone(a: Array[Array[Int]]) =
createArrays(a.size, a(0).size, (row, col) => a(row)(col))


Here I changed from private to protected, as I decided if I ever subclassed it, there would be no point in hiding these methods. I do not publish them, though, because they are helper methods, instead of methods acting upon the object itself.

Next, a.size and a(0).size were a bit cryptic, weren’t they? When we work on the matrices algorithms, it would be preferable to call them by what they are:


val rows = array.size
val cols = array(0).size


We would also like to be able to get a particular row or a particular column. It seems getting a particular row would be easy. Just return the subarray:


def row(n : Int): Array[Int] = self(n)


There is a serious problem with that, though. I’m returning a mutable object from my own internal data! We could solve that with clone, but clone only worked for bi-dimensional arrays. Well, before we create new clone, let’s consider a simpler alternative:


private def _row(n: Int): Array[Int] = self(n)
def row(n: Int): Array[Int] = _row(n) map (x => x)


The private definition is here so we can avoid creating new arrays unnecessarily. Internally, we’ll make sure we never change the value of our arrays. The public method creates a new array by the magic of “map”. The method “map” is, in fact, used when you do a for/yield, along with flatMap when the for/yield has multiple iterators. So, in fact, the createArrays method is actually implemented as using map.

A map will take a collection and produce a new collection with a given mapping. In this case, our mapping is (x => x), or, in other words, given x, return x, producing a copy of that array. We define cols in a likewise fashion:


private def _col(n: Int): Array[Int] = self map (_(n))
def col(n: Int): Array[Int] = _col(n)


In this case, the private definition and the public definition are the same. Still, I decided to keep a private definition so that I could use _row and _col throughout my class. We’ll also define a method to access a particular element of our matrix:


def apply(i: Int, j: Int): Int =
if (i >= rows || j >= cols || i < 0 || j < 0)
throw new IndexOutOfBoundsException
else
self(i)(j)


The method “apply” has a special meaning in Scala, as the compiler translates object(parms) into object.apply(parms). This means that I will be able to access a particular element of a matrix m with “m(i,j)”. Of course, because a matrix has bounds, I must test for them, and throw an appropriate exception if need be.

Note that I do not declare an @throws annotation, though I might if I wished to. Also, note that I’m returning the result of the if/else expression, and its type should be Int. But in the if statement, I’m throwing an exception, so what gives?

As it happens, throwing an exception has type Nothing, which is subtype to everything. I’m not sure if the compiler actually assigns a type to “throw”, as this is a keyword. But if I used Scala’s library “error” function instead, the question of the type would be important. For methods and functions which never return, such as error, declaring its type to be Nothing makes it possible to make use of them inside statements whose return type is important.

We’ll stop today with just three more definitions. Let’s multiply a matrix by an integer, producing a new matrix, as well as add and subtract two arrays. Here is how:


def *(n: Int): MatrixInt =
new MatrixInt(createArrays(rows, cols, (row, col) => this(row,col) * n))

def +(other: MatrixInt): MatrixInt =
if (rows != other.rows || cols != other.cols)
throw new IllegalArgumentException
else
new MatrixInt(createArrays(rows, cols, (row, col) => this(row,col) + other(row,col)))

def -(other: MatrixInt): MatrixInt =
if (rows != other.rows || cols != other.cols)
throw new IllegalArgumentException
else
new MatrixInt(createArrays(rows, cols, (row, col) => this(row,col) - other(row, col)))

Thursday, June 18, 2009

Equality & Scala 3

This one is a quickie. I forgot -- again -- to mention that Scala does provide a way around having to define your own equals method. To be more specific, case classes come with reasonably defined equals methods.

Wednesday, June 17, 2009

Equality & Scala 2

My efforts, yesterday, to come up with an Equatable trait that could ease a bit the knowledge and sheer drudgery of making a valid “equals” method met with unexpected difficulties. While tempted to replace the incorrect code with a correct one before the article got many hits, I decided that the problems I encountered and the mistakes I made taught a lesson by itself.

Anyway, I'd like first to make a few remarks that were missing from that post. One thing to notice here is that while this trait might be useful to some people, it is slower than a well thought-out equals definition. What I'm trying to do is see how much Scala let me make the job of creating valid equals methods both easier and safer.

It all comes down to the idea that, being equality in languages with subclassing so full of pitfalls, and the general solution to it being a well-defined pattern, those languages ought to be doing something about it at the language level. Or library level, if possible.

It does cross my mind that this problem might be much more efficiently and elegantly solved in languages which makes it possible to generate code at compile time, such as Lisp with its macros, and Ruby with access to the AST. This is one thing I miss in Scala, and while I understand the reasons for it and empathize with them, I do come up some roadblocks to a scalable language now and then.

That said, let’s analyze what happened. I tried to model my trait after the Hashable class. There are two things, though, that made my job harder than Hashable’s. First, I depended on super.equals, while hashCode doesn’t depend on its super. This becomes important as super.equals would make reference to definitions such as testSuperEquals or equateValues, and these definitions would be overridden in the subclass. Therefore, when Point3D.equals called Point.equals (its super.equals), the method Point.equals would make use of Point3D.equateValues and Point3D.testSuperEquals instead of Point.equateValues and Point.testSuperEquals.

This is difficult enough to get around, but it gets worse because, as opposed to hashCode, equals has to reference not one, but two objects. Calling a super of oneself is easy. Not so calling a super to a method on another object.

Another problem is the warning about type erasure. The case match never tests for type "This", so it is necessary to resort to reflection, to make sure we don't try to assign a superclass to a subclass. I didn't get any error on that because the hash test was returning false first. Well, fixed that, and changed the test code to produce constant hashCode.

The goal, then, is to make equals independent on any definition that might get overridden by later equals. Or, in other words, independent of any other definition related to the trait Equatable itself. Of course, it still will need to access members of the other object, and those might get overridden. That, however, is expected and shouldn’t have any influence on the equals method.

To begin with, let’s think how our equals definition would look like in the class. In the next to last definition, we had this:


override def equals(other : Any) = equalsTo[Point](other, true)

where equals was defined as

protected def equalsTo[This <: Equatable](other : Any, superEquals : => Boolean) : Boolean

This definition delegates to the class the task of calling super.equals – or passing “true” if not appropriate. We can’t do that inside equalsTo, because the equalsTo method is never overridden. “Super”, inside it, will have only one meaning. So this solution will do.

Now, how do we deal with equateValues? One obvious solution would be doing this:

protected def equalsTo[This <: Equatable](other : Any, equateValues : Seq[Any], superEquals : => Boolean) : Boolean

There are at least two reasons this isn’t going to work. First, while it solves the problem of equateValues on “this” object, as it get passed as a parameter on equals’ definition, it doesn’t solve it for “that” object! In fact, we now have no way of finding out what are the elements to be compared in the other object.

A second problem, though, might not be as obvious. We might depend on mutable data or data which isn’t computed yet at the time we define equals. Getting around that is possible, but would be much worse than defining an equals method by oneself!

So, what we’ll do is pass a function instead. A function which, given a “that” object, returns the sequence we need. Or, in other words, we want a object of this type:

(that : This) => Seq[Any]

The only problem with that is that “this” inside our trait does not have type This. We’ll need to receive a reference to ourselves, properly typed! Our definition, then, should be:

protected def equalsTo[This <: Equatable](self : This, other : Any, equateValues : This => Seq[Any], superEquals : => Boolean) : Boolean

The body of our function, then, becomes:

(other : @unchecked) match {
case that : This =>
(
that.canEqual(this)
&& superEquals
&& hashCode == that.hashCode // Can speed up or slow down
&& equateValues(self).zip(equateValues(that)).foldLeft(true) {
(equals, tuple) => equals && tuple._1 == tuple._2
} && equateValues.size == that.equateValues.size
)
case _ => false
}}
}

Now, how would our equals definition look like? Here:

override def equals(other : Any) = equalsTo[Point](this, other, that => List(that.x, that.y), true)
override def equals(other : Any) = equalsTo[Point3D](this, other, that => List(that.z), super.equals(other))

For big objects, inserting the function in the parameters might be awkward. Instead, we might prefer to assign the function to a val first. For example:

private val pointValues = (that : Point) => List(that.x, that.y)

So, here’s everything together, with a bit of further editing for performance resons:

trait Equatable extends scala.util.Hashable {
def canEqual (that : Any) : Boolean

protected def equalsTo[This <: Equatable](self : This, other : Any, equateValues : This => Seq[Any], superEquals : => Boolean) : Boolean =
(other : @unchecked) match {
case that : This if self.getClass.isAssignableFrom(that.getClass) =>
// Testing for hash code can improve or decrease performance, depending on the implementation;
// if hashCode gets implemented as a val, it will make equality faster
if (that.canEqual(this) && superEquals && hashCode == that.hashCode) {
val thisValues = equateValues(self)
val thatValues = equateValues(that)
(thisValues.zip(thatValues).foldLeft(true) { (equals, tuple) => equals && tuple._1 == tuple._2 }
&& thisValues.size == thatValues.size)
} else false
case _ => false
}
}

class Point (val x : Int, val y : Int) extends Equatable {
override def toString = "(%d, %d)" format (x, y)

// Hashable definitions
// override def hashValues = List(x, y)
override def hashValues = List(0) // We don't want the hash skipping our tests

// Equatable definitions
private val pointValues = (that : Point) => List(that.x, that.y) // one way
override def equals(other : Any) = equalsTo[Point](this, other, pointValues, true)
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point]
}

class Point3D(x : Int,y : Int, val z : Int) extends Point(x,y) with Equatable {
override def toString = "(%d, %d, %d)" format (x, y, z)

// Hashable defintions
// override def hashValues = List(x, y, z)
override def hashValues = List(0) // We don't want the hash skipping our tests

// Equatable defintions
// private val point3DValues = (that : Point3D) => List(that.z)
override def equals(other : Any) = equalsTo[Point3D](this, other, that => List(that.z), super.equals(other))
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point3D]
}


And the tests. I thought about doing them as assertions, but it was too silent for my taste. Anyway,

scala> val x = new Point(1, 2); val x2 = new Point(1, 2)
x: Point = (1, 2)
x2: Point = (1, 2)

scala> x == x2 // super.equals does not get called, so we do not perform reference equality
res0: Boolean = true

scala> val y = new Point(2, 1)
y: Point = (2, 1)

scala> x == y // expected false
res1: Boolean = false

scala> val z = new Point3D(1, 2, 0)
z: Point3D = (1, 2, 0)

scala> x == z // false in that canEqual this test
res2: Boolean = false

scala> z == x // false through reflection isAssignableFrom
res3: Boolean = false

scala> val z2 = new Point3D(2, 1, 0)
z2: Point3D = (2, 1, 0)

scala> z == z2 // expected false
res4: Boolean = false

scala> val z3 = new Point3D(1, 2, 0)
z3: Point3D = (1, 2, 0)

scala> z == z3 // expected true
res5: Boolean = true

scala> val z4 = new Point3D(1, 2, 1)
z4: Point3D = (1, 2, 1)

scala> z == z4 // extected false
res6: Boolean = false

scala> x == x
res7: Boolean = true

Tuesday, June 16, 2009

Equality & Scala

I'm just through reading three different sources on equality in less than a week. They all said pretty much the same thing, with a minor variation here or there. It got me thinking about it, and I have some thoughts to share. For this discussion, I'll assume you are familiar with how to do equality correctly. My examples follow the model given in this article.

Let's start with two simple classes:



class Point (val x : Int, val y : Int) {
override def toString = "(%d, %d)" format (x, y)
}

class Point3D (x : Int, y : Int, val z : Int) extends Point(x,y) {
override def toString = "(%d, %d, %d)" format (x, y, z)
}


Now, a proper equality method in these classes would look like the following:



class Point (val x : Int, val y : Int) {
override def toString = "(%d, %d)" format (x, y)
override def hashCode = 41 * (41 + x) + y
override def equals(other : Any) : Boolean = other match {
case that : Point => (
that.canEqual(this)
&& this.x == that.x
&& this.y == that.y
)
case _ => false
}
def canEqual(other : Any) : Boolean = other.isInstanceOf[Point]
}

class Point3D (x : Int, y : Int, val z : Int) extends Point(x,y) {
override def toString = "(%d, %d, %d)" format (x, y, z)
override def hashCode = 41 * (41 * (41 + x) + y) + z
override def equals(other : Any) : Boolean = other match {
case that : Point3D => (
that.canEqual(this)
&& super.equals(that)
&& this.z == that.z
)
case _ => false
}
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point3D]
}

Now, Scala has, starting with version 2.8, a Hashable trait, with which we can simplify things:



class Point (val x : Int, val y : Int) extends scala.util.Hashable {
override def toString = "(%d, %d)" format (x, y)
override def hashValues = List(x, y)
override def equals(other : Any) : Boolean = other match {
case that : Point => (
that.canEqual(this)
&& this.x == that.x
&& this.y == that.y
)
case _ => false
}
def canEqual(other : Any) : Boolean = other.isInstanceOf[Point]
}

class Point3D (x : Int, y : Int, val z : Int) extends Point(x,y) {
override def toString = "(%d, %d, %d)" format (x, y, z)
override def hashValues = List(x, y, z)
override def equals(other : Any) : Boolean = other match {
case that : Point3D => (
that.canEqual(this)
&& super.equals(that)
&& this.z == that.z
)
case _ => false
}
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point3D]
}

While it doesn't seem to have gained us anything, it might for larger objects, and, at any rate, it removes the "magic" of a hash code, and let someone else worry how to do it.

Still, there's a lot of stuff in there just to get equality right, and these are pretty simple classes. What we see is a programming pattern, but one so common and so important that, in my opinion, it merits special attention from the language itself.

Barring that, let's see what we can do programmatically about it. I'll start with a helper function, and how it would be used:



def testEquality(one : AnyRef, other : AnyRef, elementsOne : Seq[Any], elementsOther : Seq[Any]) : Boolean = {
val classOfOne = one.getClass
val classOfOther = other.getClass

def sameClassOrSubclass: Boolean = classOfOne.isAssignableFrom(classOfOther)

def superEquals : Boolean = try {
val superEqualsMethod = classOfOne.getSuperclass.getMethod("equals", classOf[Any])
if (superEqualsMethod.getDeclaringClass != classOf[Any])
superEqualsMethod.invoke(one, other) match {
case flag : java.lang.Boolean => flag.booleanValue // Translate boxed boolean into boolean
case _ => error("Method equals on the parent class of object " + one + " does not return a boolean")
}
else true
} catch {
case _ => true
}

def canEqual : Boolean = try {
val canEqualMethod = classOfOther.getMethod("canEqual", classOf[Any])
canEqualMethod.invoke(other, one) match {
case flag : java.lang.Boolean => flag.booleanValue // Translate boxed boolean into boolean
case _ => error("Method canEqual on object " + other + " does not return a boolean")
}
} catch {
case _ => true
}

def elementsEquals : Boolean = {
elementsOne.zip(elementsOther).foldLeft(true) {
(equals, pair) => equals && pair._1 == pair._2
} && elementsOne.size == elementsOther.size
}

(sameClassOrSubclass(classOfOne, classOfOther)
&& canEqual
&& superEquals
&& elementsEquals
)
}

class Point (val x : Int, val y : Int) extends scala.util.Hashable {
override def toString = "(%d, %d)" format (x, y)

// Hashable
override def hashValues = List(x, y)

// Equality
override def equals(other : Any) : Boolean = other match {
case that : Point => testEquality(this, that, List(x, y), List(that.x, that.y))
case _ => false
}
def canEqual(other : Any) : Boolean = other.isInstanceOf[Point]
}

class Point3D(x : Int,y : Int, val z : Int) extends Point(x,y) {
override def toString = "(%d, %d, %d)" format (x, y, z)

// Hashable
override def hashValues = List(x, y)

// Equality
override def equals(other : Any) : Boolean = other match {
case that : Point3D => testEquality(this, that, List(x, y, z), List(that.x, that.y, that.z))
case _ => false
}
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point3D]
}

Now, this method always calls the parent's equals, unless it's Any's equals. You might want to parametrize this. Also, it expects canEqual to be defined if needed, which might lead to bugs. Furthermore, its usage of reflection makes it slower than needed. Finally, the definition of equals is not that much simpler than what we had before.

So, can we do better? Ideally, one could build a trait similar to Hashable, but it turns out that is not that simple. Let's try:



trait Equatable extends scala.util.Hashable {
protected type EquateThis <: Equatable
private def equalsFromAny : Boolean = {
this.getClass.getSuperclass.getMethod("equals", classOf[Any])
.getDeclaringClass == classOf[Any]
}

protected def equateValues : Seq[Any]

def canEqual (that : Any) : Boolean = true

abstract override def equals(other : Any) : Boolean = (other : @unchecked) match {
case that : EquateThis =>
(
that.canEqual(this)
&& (equalsFromAny || super.equals(that))
&& hashCode == that.hashCode // Can speed up or slow down
&& equateValues.zip(that.equateValues).foldLeft(true) {
(equals, tuple) => equals && tuple._1 == tuple._2
} && equateValues.size == that.equateValues.size
)
case _ => false
}
}

class Point (val x : Int, val y : Int) extends Equatable {
override def toString = "(%d, %d)" format (x, y)

// Hashable definitions
override def hashValues = List(x, y)

// Equatable definitions
override type EquateThis = Point
override def equateValues = List(x, y)
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point]
}

class Point3D(x : Int,y : Int, val z : Int) extends Point(x,y) with Equatable {
override def toString = "(%d, %d, %d)" format (x, y, z)

// Hashable defintions
override def hashValues = List(x, y, z)

// Equatable defintions
override type EquateThis = Point3D
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point3D]
override def equateValues = List(z)
}


That looks more like it, but it has a few problems still. It still uses reflection, for one thing, to test for super's equals method. Also, you can't parametrize that is it is. It won't get Equatable's own equals, though, as traits compiles down to part of the class being defined, not as an ancestor to it.

Next, it has a default for canEqual, and a dangerous one at that. If the programmer forgets to override it, it will lead to trouble.

But, most importantly, it doesn't work. The class Point3D can't override Point's definition for type EquateThis. I don't understand precisely why this is the case, and I'd be glad if anyone stepped in to explain this.

Anyway, let fix these problems:



trait Equatable extends scala.util.Hashable {
protected def testSuperEquals : Boolean
protected def equateValues : Seq[Any]
def canEqual (that : Any) : Boolean

protected def equalsTo[This <: Equatable](other : Any) : Boolean = (other : @unchecked) match {
case that : This =>
(
that.canEqual(this)
&& ((!testSuperEquals) || super.equals(that))
&& hashCode == that.hashCode // Can speed up or slow down
&& equateValues.zip(that.equateValues).foldLeft(true) {
(equals, tuple) => equals && tuple._1 == tuple._2
} && equateValues.size == that.equateValues.size
)
case _ => false
}
}

class Point (val x : Int, val y : Int) extends Equatable {
override def toString = "(%d, %d)" format (x, y)

// Hashable definitions
override def hashValues = List(x, y)

// Equatable definitions
override def testSuperEquals = false
override def equateValues = List(x, y)
override def equals(other : Any) = equalsTo[Point](other)
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point]
}

class Point3D(x : Int,y : Int, val z : Int) extends Point(x,y) with Equatable {
override def toString = "(%d, %d, %d)" format (x, y, z)

// Hashable defintions
override def hashValues = List(x, y, z)

// Equatable defintions
override def testSuperEquals = true
override def equals(other : Any) = equalsTo[Point3D](other)
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point3D]
override def equateValues = List(z)
}
This finally get us where we wanted. Or as close to as I could, at least. :-)

The definition of canEqual is made abstract. That forces the first class to mix Equatable in to define it, even if to a default of "true". Next, instead of trying to figure out if equality must be called on the super, we simply require the class to tell us.

Finally, the equals method. We can't (or I couldn't) get the trait to define it, but I got pretty close. In the end, class still has to define an equals method, but that method pretty much gets reduced to a simple call to one defined in the trait, passing the object being compared to and the class expected. The class expected gets passed as an explicit type parametrization.

Neat. I didn't think I'd be able to get this much! Now, who's going to port it to Java?


Update:
Ok, I spoke too soon. This method fails here:



scala> val x = new Point(1, 2); val x2 = new Point(1, 2)
x: Point = (1, 2)
x2: Point = (1, 2)

scala> x == x2 // super.equals does not get called, so we do not perform reference equality
res7: Boolean = true

scala> val y = new Point(2, 1)
y: Point = (2, 1)

scala> x == y // expected false
res8: Boolean = false

scala> val z = new Point3D(1, 2, 0)
z: Point3D = (1, 2, 0)

scala> x == z // false in the canEqual call
res9: Boolean = false

scala> z == x // false in the type check
res10: Boolean = false

scala> val z2 = new Point3D(2, 1, 0)
z2: Point3D = (2, 1, 0)

scala> z == z2 // false in the super.equals call
res11: Boolean = false

scala> val z3 = new Point3D(1, 2, 0)
z3: Point3D = (1, 2, 0)

scala> z == z3 // false in the super.super.equals call - it should have been true
res12: Boolean = false

Anyone up for fixing it?

Update 2:
Ok, I fixed it. I resorted to delegating this task to the calling class. That means I do away with testSuperEquals, but require a second parameter to equalsTo. I make it by name, so that it doesn't get evaluated needlessly.


trait Equatable extends scala.util.Hashable {
protected def equateValues : Seq[Any]
def canEqual (that : Any) : Boolean

protected def equalsTo[This <: Equatable](other : Any, superEquals : => Boolean) : Boolean = (other : @unchecked) match {
case that : This =>
(
that.canEqual(this)
&& superEquals
&& hashCode == that.hashCode // Can speed up or slow down
&& equateValues.zip(that.equateValues).foldLeft(true) {
(equals, tuple) => equals && tuple._1 == tuple._2
} && equateValues.size == that.equateValues.size
)
case _ => false
}}
}

class Point (val x : Int, val y : Int) extends Equatable {
override def toString = "(%d, %d)" format (x, y)

// Hashable definitions
override def hashValues = List(x, y)

// Equatable definitions
override def equateValues = List(x, y)
override def equals(other : Any) = equalsTo[Point](other, true)
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point]
}

class Point3D(x : Int,y : Int, val z : Int) extends Point(x,y) with Equatable {
override def toString = "(%d, %d, %d)" format (x, y, z)

// Hashable defintions
override def hashValues = List(x, y, z)

// Equatable defintions
override def equals(other : Any) = equalsTo[Point3D](other, super.equals(other))
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point3D]
override def equateValues = List(z)
}

And the testing:


scala> val x = new Point(1, 2); val x2 = new Point(1, 2)
x: Point = (1, 2)
x2: Point = (1, 2)

scala> x == x2 // super.equals does not get called, so we do not perform reference equality
res105: Boolean = true

scala> val y = new Point(2, 1)
y: Point = (2, 1)

scala> x == y // expected false
res106: Boolean = false

scala> val z = new Point3D(1, 2, 0)
z: Point3D = (1, 2, 0)

scala> x == z // false in the canEqual call
res107: Boolean = false

scala> z == x // false in the type check
res108: Boolean = false

scala> val z2 = new Point3D(2, 1, 0)
z2: Point3D = (2, 1, 0)

scala> z == z2 // false in the super.equals call
res109: Boolean = true

scala> val z3 = new Point3D(1, 2, 0)
z3: Point3D = (1, 2, 0)

scala> z == z3 // expected true
res110: Boolean = true

Update 3:
This is still seriously broken, as the very test above indicates. What is happening is that when super.equals gets called, it uses this.equateValues instead of the super's version of it. It might be easy to fix for "this", but not for "that". At this point, I'm giving up on super.equals. Let's assume the equality for all classes is defined by the equalsTo method, and require a call to super.equateValues at every subclass (that finds it necessary). Here it is


trait Equatable extends scala.util.Hashable {
protected def equateValues : Seq[Any]
def canEqual (that : Any) : Boolean

protected def equalsTo[This <: Equatable](other : Any) : Boolean = (other : @unchecked) match {
case that : This =>
(
that.canEqual(this)
&& hashCode == that.hashCode // Can speed up or slow down
&& equateValues.zip(that.equateValues).foldLeft(true) {
(equals, tuple) => equals && tuple._1 == tuple._2
} && equateValues.size == that.equateValues.size
)
case _ => false
}}
}

class Point (val x : Int, val y : Int) extends Equatable {
override def toString = "(%d, %d)" format (x, y)

// Hashable definitions
override def hashValues = List(x, y)

// Equatable definitions
override def equateValues = List(x, y)
override def equals(other : Any) = equalsTo[Point](other)
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point]
}

class Point3D(x : Int,y : Int, val z : Int) extends Point(x,y) with Equatable {
override def toString = "(%d, %d, %d)" format (x, y, z)

// Hashable defintions
override def hashValues = List(x, y, z)

// Equatable defintions
override def equals(other : Any) = equalsTo[Point3D](other)
override def canEqual(other : Any) : Boolean = other.isInstanceOf[Point3D]
override def equateValues = z :: super.equateValues
}

And test:


scala> val x = new Point(1, 2); val x2 = new Point(1, 2)
x: Point = (1, 2)
x2: Point = (1, 2)

scala> x == x2 // super.equals does not get called, so we do not perform reference equality
res138: Boolean = true

scala> val y = new Point(2, 1)
y: Point = (2, 1)

scala> x == y // expected false
res139: Boolean = false

scala> val z = new Point3D(1, 2, 0)
z: Point3D = (1, 2, 0)

scala> x == z // false in the canEqual call
res140: Boolean = false

scala> z == x // false in the type check
res141: Boolean = false

scala> val z2 = new Point3D(2, 1, 0)
z2: Point3D = (2, 1, 0)

scala> z == z2 // expected false
res142: Boolean = false

scala> val z3 = new Point3D(1, 2, 0)
z3: Point3D = (1, 2, 0)

scala> z == z3 // expected true
res143: Boolean = true


Thursday, June 11, 2009

Using Implicits to Select Types

Scala 2.8's collection revision is doing interesting things. The most obvious one will be the methods revision. One thing that shouldn't be all that obvious, though, is how much code will be shared, and how that shared code will still look like it was specific to a class.

I'll quote here a couple of examples from the Scala 2.8 Collection's Whitepaper (pdf at the bottom):



scala> "abc" map (x => (x + 1).toChar)
res1: scala.runtime.RichString = bcd

scala> "abc" map (x => (x + 1))
res2: scala.collection.immutable.Vector[Int] = Vector(98, 99, 100)

scala> Map("a" -> 1, "b" -> 2) map { case (x, y) => (y, x) }
res3: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a, 2 -> b)

scala> Map("a" -> 1, "b" -> 2) map { case (x, y) => y }
res4: scala.collection.immutable.Iterable[Int] = List(1, 2)


Now, this "map" method is inherited from a common trait, and yet it knows when the result of a map over a RichString is a RichString, when the result of a map over a Map is a Map, and when it's not. How can it be?

The answer is implicit parameters. One thing about implicits, is that a more specific implicit has preference over a more generic one. Take a look at this example:



scala> abstract class X[T] { def id : Unit }
defined class X

scala> implicit def a[T] = new X[T] { def id = println("generic") }
a: [T]X[T]

scala> implicit def b = new X[Int] { def id = println("Int") }
b: X[Int]

scala> def f[T](a : T)(implicit g : X[T]) = g.id
f: [T](T)(implicit X[T])Unit

scala> f(5)
Int

scala> f('c')
generic


Both "a" and "b" have the correct type, X[T]. The second definition, though, will return X[Int], which is more specific than X[T], which the first definition returns. So, whenever X[Int] is required, "b" will take precedence over "a". Naturally, if some other type of X is required, "b" won't be used at all.

This is how map can do its trick. To compose the result, it uses methods from the class Builder[-Elem, +To]. Such a build will create a collection of type To from elements of type Elem. Now, this is not enough to solve map's problem. For example, I want a RichString as result, if I'm doing a map over a RichString, but not if I'm mapping over a List of Chars. See the two examples below:



scala> "abc" map (x => (x + 1).toChar)
res1: scala.runtime.RichString = bcd

scala> List('a', 'b', 'c') map (x => (x + 1).toChar)
res11: List[Char] = List(b, c, d)


So, for methods with more complex semantics, like map, we need something else which can produce the correct Builder. For that, the trait BuilderFactory[Elem,
+To, From] exists. BuilderFactory will produce a Builder for a method which takes a collection of type From, and uses elements of type Elem to produce a collection of type To.

Now, the more generic implicit for a BuilderFactory is BuilderFactory[A, Iterable[A], Iterable[_]], which should be pretty obvious. Other implicits exists, though, such as BuilderFactory[Char, RichString, RichString]. Now, look at map's declaration:



def map[B, That](p: Elem => B)(implicit bf: BuilderFactory[B, That, This]): That


So, when you do "abc".map( x => (x + 1).toChar), the compiler knows that "B" is Char (the result of the function being mapped). "This" is known to be RichString, from the definition of class RichString itself. Now, given that "B" = Char and "This" = RichString, then BuilderFactory[Char, RichString, RichString] is a more specific match than the other implicit definitions. And, because it gets used, "That" gets defined to be RichString also, thus defining the result type for that map.

The cleverness of it is to use implicits to define unknown type parameters as a function of known type parameters. This is can be a very useful pattern for those who want to take maximum advantage of static type checking.

Case Classes and Product

It's a well-known fact that by adding "case" before "class" in Scala, the compiler will generate some scaffolding for you like making all your paremeters "val", creating apply and unapply in a companion object. etc.

It's not a particular known fact that one of the things it does is extending the class with the trait Product. This trait makes it easy to access the elements of the class, like in the example below:



scala> trait recordType {
| self : Product =>
| def records : String = (
| for(parm <- self.productIterator)
| yield parm.asInstanceOf[AnyRef].getClass.getSimpleName+": "+parm
| ) mkString "\n"
| }
defined trait recordType

scala> case class X(i : Int, c : Char, s : String) extends recordType
defined class X

scala> val x = X(5, 'd', "this")
x: X = X(5,d,this)

scala> println(x.records)
Integer: 5
Character: d
String: this

Let me talk about the trait recordType a bit first. Its body first line declares that "self : Product =>". This has two purposes. First, it creates an alias for "this". Second, and most important, it tells the compiler that to be able to use this trait, a class must mix in the trait Product.

Anyway, the code works fine for simple classes, but it might be weird for collections:



scala> case class Y(a : Array[String], l : List[Int]) extends recordType
defined class Y

scala> val y = Y(Array("this", "example"), List(1,2,3))
y: Y = Y([Ljava.lang.String;@60a517,List(1, 2, 3))

scala> println(y.records)
String[]: [Ljava.lang.String;@60a517
$colon$colon: List(1, 2, 3)

Here, Array is mucked up because Java's Array are mucked up. As for the List, any non-empty List actually belongs to class "::", a subclass of List.

Sunday, June 7, 2009

Function.tupled, Function.curried

Scala's library hides small gems of which little is said. Let me speak of a personal favorite here, the object Function.

This object has a number of methods to construct a function from another function (or others, in the case of "chain").  They are variations of "curried", "tupled", "uncurried" and "untupled". As their names makes clear, they transform a function whose arguments are not curried or are not a tuple into a function whose arguments are curried, or which receives a tuple as an argument. Take, for instance, this definition of zipMap, which applies a function of two arguments between two lists:



scala> def zipMap[A,B,C](l1 : Seq[A], l2 : Seq[B])(f : (A,B) => C) =
| l1 zip l2 map (x => f(x._1, x._2))
zipMap: [A,B,C](l1: Seq[A],l2: Seq[B])(f: (A, B) => C)Sequence[C]

scala> zipMap (List(1, 3, 9), List(5, 2, 3)) ((x,y) => x max y)
res5: Sequence[Int] = List(5, 3, 9)


This is not a bad definition, but accessing the tuple arguments to pass to f is too much mechanics for my taste. So, instead, we could do this:



scala> def zipMap[A,B,C](l1 : Seq[A], l2 : Seq[B])(f : (A,B) => C) =
| l1 zip l2 map Function.tupled(f)
zipMap: [A,B,C](l1: Seq[A],l2: Seq[B])(f: (A, B) => C)Sequence[C]

scala> zipMap (List(1, 3, 9), List(5, 2, 3)) ((x,y) => x max y)
res4: Sequence[Int] = List(5, 3, 9)


Much better, don't you think? By the way, this was done on 2.8, where Seq has the method zip.

Friday, June 5, 2009

Scalable Algorithms 3

Back to matching shortcuts to menu options, I decided my best option would be a deterministic finite automaton. It would make excellent use of partial input, and take much less space than a set of all possible inputs accepted -- to make use of state machine lingo -- by each menu option.

Now, anyone who has ever worked with DFA before will tell you that the trick to build one is to first generate the regular expression which represents what you want to match. Yes, that's your good, old RegExp. Well, not fully... you can't have back references, for one thing. But most of what you think of as regexp will do.

So, what regular expression would match our input? Let's take a small menu option: "New Tab". We want to accept either word as well as its abbreviation, so "New", "Tab" and "NT" should be matched. Any prefix of either word should be taken as well, so we add "N", "Ne", "T" and "Ta" to it. Finally, we want to combine word prefixes, like "NTab" or "NeTa", you get the idea.

So, let's get the first word, and see how far we can take. We have "N", "Ne" and "New". So "N" is mandatory, and "e" is optional. That would be "Ne?" in regexp. Next, "w" is also optional, but it can only appear if "e" appears as well. That's "N(ew?)?" in regexp, or, to make regular use of parenthesis, "N(e(w)?)?". Now, since we may as well only match the second word, the whole first word is optional, which gives us "(N(e(w)?)?)?".

Naturally, each word would follow the same pattern, but what about the whole menu option? As it happens, you only have to concatenate the patterns: "(N(e(w)?)?)?(T(a(b)?)?)?". It should be pretty simply to create such a function.

In fact, we can do it using foldRight. As you know, foldRight combines things from right to left, using the result of the last operation and the next element. Now, it may not be immediately obvious what the operation is, so let's assume we already processed "w". That means we have "(w)?" as the last result, and "e" as the next letter, and the result we want to come up with is "(e(w)?)?". It's trivial to see, then, that the operation is "("+"e"+"(w)?"+")?".

Now that we know what the operation is, let's think about the initial "result" that fold takes as parameter. We want x in "("+"w"+x+")?". Since that must be equal to "(w)?", x = "".

Ok, so now we know what the regular expression for a menu option must look like, as well as how to build one from its string. We can now proceed to building a DFA.

But... we can match regular expressions to strings just as well as DFA. I might not take advantage of partial inputs, and I can't go the next step, which is creating one DFA which will accept all menu options and, as an added bonus, have the associated menu options at each state.

Still, how hard would it be to match against regexp? Well, let's try...



val wordsep = "\\W+"
def words(s : String) = s.split(wordsep)
def phraseRegex(s : String) =
"^" + words(s).map(_.foldRight("")("(" + _ + _ + ")?")).mkString
def regexList(l : List[String]) = l.map(s => phraseRegex(s) -> s)
def regexSearcher(l : List[String]) = {
val r = regexList(l)
(s : String) => r.filter(s matches _._1).map(_._2)
}


That's it. You could, and should improve it by pre-compiling the regexp expressions. It's a bit uglier, but for the sake of doing things right, I'll post it at the end. Anyway, this is fairly inexpensive in terms of memory usage, and regexp matches are very fast. I doubt it can beat a hash tree, but it should give it a run for its money. Still, the fact that you'll be matching every menu option against the input is problematic, and the hash tree doesn't suffer that problem. The setup time for this algorithm should be pretty fast too, even precompiling the regexp.

Anyway, it's short, it's obvious, and it's not too shabby. We'll next get into DFA, and do it by using Scala's standard library. That should be the worst of all algorithms, but a stepping stone to the last one I'll present. For now, here's the revised code.



val wordsep = "\\W+"
def words(s : String) = s.split(wordsep)
def phraseRegex(s : String) =
("^" + words(s).map(_.foldRight("")("(" + _ + _ + ")?")).mkString).r
def regexList(l : List[String]) = l.map(s => phraseRegex(s) -> s)
def regexSearcher(l : List[String]) = {
val r = regexList(l)
(s : String) => r.filter(_._1.findPrefixOf(s) == Some(s)).map(_._2)
}

Wednesday, June 3, 2009

Compiling Remotely

As you may know, the fsc compiler, the recommended way to compile Scala, and used by the Scala interpreter by default, detaches a daemon service the first time it is run. After that, fsc will always call the daemon service to compile for it, to save time.

It does this through TCP, which begs the question... can I compile remotely? The answer is Yes! It's not documented, and it is a bit awkward, but...

First, you get fsc running on the server by running fsc -verbose, like this:



$fsc -verbose
[Server arguments: -d C:\Users\Daniel\Documents\Programas\. -verbose]
[VM arguments: ]
[Temp directory: C:\PROGRA~1\Scala\bin\..\var\scala-devel]
[Executed command: C:\PROGRA~1\Scala\bin\..\bin\scala.bat scala.tools.nsc.CompileServer]
[Port number: 1385]
[Connected to compilation daemon at port 1385]
Usage: fsc
where possible standard options include:
-g: Specify level of generated debugging info (none,source,line,vars,notailcalls)
-nowarn Generate no warnings
-verbose Output messages about what the compiler is doing
-deprecation Output source locations where deprecated APIs are used
-unchecked Enable detailed unchecked warnings
-classpath Specify where to find user class files
-sourcepath Specify where to find input source files
-bootclasspath Override location of bootstrap class files
-extdirs Override location of installed extensions
-d Specify where to place generated class files
-encoding Specify character encoding used by source files
-target: Specify for which target object files should be built (jvm-1.5,jvm-1.4,msil)
-print Print program with all Scala-specific features removed
-optimise Generates faster bytecode by applying optimisations to the program
-explaintypes Explain type errors in more detail
-uniqid Print identifiers with unique names for debugging
-version Print product version and exit
-help Print a synopsis of standard options
-X Print a synopsis of advanced options
@<file> A text file containing compiler arguments (options and source files)

This will get you the port number. Next, you can compile whatever you like from a remote client like this:

$fsc -server 192.168.1.35:1385 strategy.scala

That's it. Cool, eh?

Parser Surprise

David Vydra found it surprising that he couldn't do the following:

scala> -1.toString
:1: error: ';' expected but '.' found.
-1.toString
^


I was surprised too by some similar example, from page 208 of Programming in Scala: A Comprehensive Step-by-step Guide.

Given that example, I would not expect that message in particular, but I would expect an error: that "unary_-" is not a member of java.lang.String, like this:

scala> -(1 toString)
:5: error: value unary_- is not a member of java.lang.String
-(1 toString)
^


Or, in fact, like this:

scala> +1.toString
:5: error: value unary_+ is not a member of java.lang.String
+1.toString
^


Some people have raised the question of operator precedence, claiming "-" ought to have more precedence than ".". It might seems reasonable in this example, where "1" is obviously an integer literal. But what about "-object.size"? Would you expect it to negate the object's size, or to negate the object and then return the size?

So let's take a look at Scala's operator precedence rule. The rules states that, with a sole excetion, the precedence, from the lowest to the highest, is based on an operator's first character as follow:

(all letters)
|
^
&
< >
= !
:
+ -
* / &
(all other special characters)

The exception is that an assignment has lower precedence than any other operator. Because of this excection, += -- an assignment -- has lower precedence than <=, the less-than-or-equal-to operator, even though operators starting with + have precedence over those starting with "<".

These, though, are the precedence rules for infix operators, and "-" in "-1" is not infix, but prefix. So, does infix precedence applies for prefix operators? No, as the example below shows:

scala> class X {
| def unary_- = {println("Unary -"); this}
| def *(b : X) = {println("operator *"); this}
| def -(b : X) = {println("operator -"); this}
| override def toString = "class X"
| }
defined class X

scala> new X
res16: X = class X

scala> new X
res17: X = class X

scala> -res16 * res17
Unary -
operator *
res18: X = class X

scala> res16 - res17 * res16
operator *
operator -
res19: X = class X


So we can see clearly that unary_- has precence over "*", which, itself, has precedence over "-".

So, back to ".", what is happening? Well, for one thing, "." is not an operator. Dot is considered an operator in some other languages. In Scala, though, it is a syntactic construct. If it were an operator, you would be able to define it in a class. As it is, it's a reserved symbol. So any operator will only be considered after resolving ".".

Still, again, why isn't the error as follow?

scala> -(1 toString)
:5: error: value unary_- is not a member of java.lang.String
-(1 toString)
^


Johannes Rudolph has since investigated this further. Here is his analysis:


Originally(*), and despite of the language specification (**),
negative number literals could not appear in a select expression
(-1.max(5)). Since [19950] which 'fixed' #2378 (***), the balance
between integer and floating point literals drifted: for with what the
parser was concerned, negative floating point literals received no
special treating any more, so -5f.max(2) was seen as
(5f.max(2)).unary_-, simple negative floating literals as 5f.unary_-
(*!*). For negative integer literals the situation stayed the way it
was the way before: -1.max(5) was simply not allowed by the parser.
(*) That's [3930], the commit with the unimpressive empty log message
where nsc sprang to life.
(**) The SLS would allow both 5.unary_- and the literal -5 and does at
least not specify how to resolve this ambiguity.
(***) The real cause of #2378 can be found in the backyard of the
backend: FJBG generates a DCONST_0 if a double literal == 0.0, what
-0.0 is.
(*!*) This behaviour caused #3486, where negative constants in
annotations wouldn't be possible any more.

Tuesday, June 2, 2009

Scalable Algorithms 2

In my last post, I told of a programming challenge taken, and my first go at it. While the algorithm I came up with had a certain cleverness, there was much to criticize about it.

Another friend, who had received the same challenge, attacked the problem from a different perspective. His algorithm was not as liberal with the input as mine, as it accepted only abbreviations or single words. It would match a prefix of a word other than the first one, though, which is something mine didn't.

For instance, if there was an option "create application shortcuts", it would match that against "cas" or any prefix of it (eg. "ca"), "create" or any prefix of it, "application" or any prefix of it and "shortcuts" or any prefix of it.

Map of Prefixes

I won't post his algorithm of it here (though I'd be happy to link to a post of his, if he does so), but the idea was precomputing a couple of maps: one of full abbreviations into set of menu options, and one of words into set of menu options.

The cleverness of it, though, is that he did not precompute all possible prefixes. Instead, he used ranges, close-ended at the input being matched, and open ended at the input being matched with the last character replaced by it's successor, and applied that range to the keys of each map. The result was that all keys to which the input was a prefix of would be selected.

Now, there were two things about his algorithm I didn't like. First, it would use mutable sets and maps when precomputing. I was trying to avoid that. Second, it would not match a concatenation of the prefix of different words, so appshort would match the example previously given.

So I decided to take a shot at it, which, sadly, did not benefit from the range cleverness. As before, I'll follow the code with my criticisms of it.


val wordsep = "[ :,;]"
def words(s : String) = s.split(wordsep)
def wordPrefixes(s : String) = (0 to s.length).map(s.substring(0,_))
def combinedPrefixes(s : String) =
words(s).foldLeft(Set(""))((set, word) =>
set.flatMap(x => wordPrefixes(word).map(y => x + y)))

def reversePhraseMap(l : List[String]) =
l.foldLeft(Map[String,Set[String]]())((map, phrase) =>
map + (phrase -> combinedPrefixes(phrase)))

def allPrefixes(m : Map[String,Set[String]]) = m.values.reduceLeft(_ ++ _)

def phraseMap(m : Map[String,Set[String]]) =
Map[String,Set[String]]() ++ allPrefixes(m).
map(p => p -> m.foldLeft(Set[String]())((s, x) =>
if(x._2.contains(p)) s + x._1 else s))

def indexPhrases(l : List[String]) = phraseMap(reversePhraseMap(l))

def searchPhrases(l : List[String]) = {
val index = indexPhrases(l.map(_.toLowerCase))
(s : String) => index(s.toLowerCase)
}


The way you use it is you pass a list of menu options to searchPhrases, and searchPhrases returns a function which will look up an input in the list and return the result.

Well. I'm not particularly fond of this algorithm, but the code is much more obvious, in my opinion, than the first one. I had to compute the reversed map first (ie, the menu options pointing to a set of their abbreviations), and then reverse that. I wonder if I shouldn't have reversed the definitions name, though (pun half-intended).

Now, this code is 19 lines vs the first's 34, but this isn't really enough of a difference when considers code complexity. But the first code had 4 "if" statements, all of them followed by "else" statements, one "match" statement and, to boot, a couple of mutually recursive functions. This one has a single "if". This is functional programming at it's best (well, almost best :). In fact, the whole code could be written as a single expression, a single statement:


def searchPhrases(l : List[String]) =
(s : String) => (
Map[String,Set[String]]() ++
(
(
l
map (_ toLowerCase)
foldLeft Map[String,Set[String]]()
) ((map, phrase) =>
map + (phrase ->
(
(
phrase
split "[ :,;]"
foldLeft Set("")
) ((set, word) =>
set flatMap (x => (
0
to word.length
map (word substring (0, _))
map (x + _)
)
)
)
)
)
).values
reduceLeft (_ ++ _)
map (p =>
p -> (
(
(
(
l
map (_.toLowerCase)
foldLeft Map[String,Set[String]]()
) ((map, phrase) =>
map +
(phrase -> (
(
phrase
split ("[ :,;]")
foldLeft Set("")
) ((set, word) =>
(
set
flatMap (x =>
(
0
to word.length
map (word substring (0, _))
map (x + _)
)
)
)
)
))
)
)
foldLeft Set[String]()
) ((s, x) =>
if (x._2 contains p) s + x._1 else s
)
)
)
)
) (s toLowerCase)


Now, that's a long, long expression to keep track of, and there's some repetition in it. Broken up in smaller definition helps manage the size, and the definition's names help understand what is being done.

Still, the fact the lack of control structures helps one to focus on what is being done. You don't have to keep backtracking the code and thinking what happens on that other condition. So, while both algorithms deal in immutable objects only, the more you keep to high order functions in place of control structures, the clearer becomes the code.

This algorithm has a fast search, and it can catch any variation of prefixes, as long as no words are inverted. To do that it spends some time building the map, and the map itself is very wasteful of memory. It doesn't make take advantage of character-by-character input, but it doesn't really need it. It has no heuristics to order the list of matched menu options, though, and no easy way to retrofit it. That I can see, at least.

At this point, I decided that what I wanted was a DFA matcher, but this took me to an unexpected place first. The next algorithm has 9 lines of code, two being def lines without code, one being a constant definition, and one being "}". At that, it matches everything this algorithm does. Can you beat that before my next post? :-)

Monday, June 1, 2009

Scalable Algorithms

It's common knowledge that the best way of learning a new language is writing a program you wanted in it. Or, perhaps I should say, that's the quickest way of learning a language -- you should beware of the gaps in knowledge of the language that can result from this approach.

Well, I was trying to do that with Scala, but I always stopped because there was something more I wanted to learn before continuing with one project or other. It was then that a friend posed a challenge, and that finally broke the programmer's block I was having.

He has written a small program -- in Scala -- with few but loyal followers to help in his gaming sessions, and he wanted something to help with fast keyboard selection. His idea was having an algorithm that would search available menu options based on a few input characters, which would typically stand for an abbreviation of that menu.

As I took the challenge, I formally specified the algorithm requirement to the following: given a list of phrases (representing menu options) and a string of characters (representing user input), select all phrases for which exists a combination of prefixes of arbitrary length whose concatenation equals the string of characters.

Preferably, order the result too using some kind of heuristics.

Well, I wound up writing many solutions to the problem. Of course, there are MANY solutions to the problem -- my friend himself wrote something completely different from any of mine. But I discovered real joy in programming with Scala as I wrote them. So, let me share them with you.

List decomposition

The first concept I came up with was essentially based on lists. Scala has brought me back with full force to the lists algorithms I used once with functional languages.

I'll follow the code with my own thoughts about it. But, first, I want to explain the basic concept. First, I transform each phrase into a list of words, each word being a list of characters. The user input also gets transformed into a list of characters. Next, for each phrase I try possible matches against the input, and return a score.

This is where it gets recursive. After matching each character to the first character of the first word in the list, I select the better of the next two possible options: matching the next character in the word, or the first character in the next word.

The heuristics I used here gives preference first for matches that consume the whole input, and, next, to matches that match most of the words in the input. As such, and keeping in mind abbreviations are the most likely input, I use a function which receives the recursion as by name parameters, and only computes the second option if the first one doesn't return a perfect match (all input consumed, no words left unmatched).

Different from the algorithms wrote next, you can't skip words when matching. Also note I severely shortened the comments, as they got a bit too lengthy for a blog.


// Given two tuples formed by the length of unmatched input and
// the number of unmatched words, choose the "best" of them.
def isBetterThan(a: (Int, Int), b: (Int, Int)) : Boolean = if (a._1 == b._1) {
if (a._2 < b._2) true else false
} else {
if (a._1 < b._1) true else false
}

// Receives two expressions by nam, who, in turn, return a tuple representing
// matching efficacy. Evaluates the first expression and, if the efficacy is
// not the best possible, evaluates the second expression and return the better
// one.
def bestOf(aL: => (Int, Int), bL : => (Int, Int)) : (Int, Int) = {
val a = aL
if( a == (0,0)) a
else {
val b = bL
if (isBetterThan(a, b)) a else b
}
}

// Try to match the first character of input and menu option. Recurse if
// succesful.
def matchInputToOption(input : List[Char], op : List[List[Char]]) : (Int, Int) = {
(input, op) match {
case (in1 :: Nil, (op11 :: op1s) :: ops) if (in1 == op11) =>
(0, ops.length)
case (in1 :: ins, (op11 :: op1s) :: ops) if (in1 == op11) =>
bestOf(matchInputToOption(ins, ops),
matchInputToOption(ins, op1s :: ops))
case (_, _) =>
(input.length, op.length)
}
}

// Listify inputs, zip menu options with computed matches, filter for
// matches which consume the whole input, sort them, return.
def searchOptions(input : String, menu : List[String]) : List[(String, Int)] = {
val inputList = input.toList
val menuList = menu.map(_.split(" ").toList.map(_.toList))

(menu
zip (menuList map (menuOp => matchInputToOption(inputList, menuOp)))
filter (_._2._1 == 0)
sort ((a,b) => isBetterThan(a._2,b._2))
map (x => (x._1, x._2._2))
)
}



This algorithm was born of matchInputToOption. I was charmed by the flexibility of match, and thinking myself oh-so-clever by realizing I could call tail on the list of words or the list of characters of the head of list of words as the only two alternatives after each match. All the rest as created to make this function work.

I do think that function is clever, and it does go to show Scala's power. The algorithm, itself, can go directly to the nearest trash can. It is easy to check it's correctness -- and please note it only works with immutable objects -- but that isn't enough to make up for its many failings.

First, I do not precompute anything, and I do require some work transforming all those strings into lists. If Scala is using projections to do it, it might not be all that bad though.

Next, it has no memory of previous matches. Each time it's called, it matches the whole input. If you happen to feed it character by character, this becomes very wasteful.

Memory-wise... well, that depends on that projection thingy. If split and toList are being strict (precomputing everything), then we have lists of characters, which are very wasteful.

It is rather fast, but there are faster ones.

And, finally, it's not particularly pretty to look at or easy to understand.

In my next post I'll show a truly memory wasteful algorithm, but a very quick one.