Scala Gets Operator Overloading Right

02/20/2010 Update: I took this blog post and turned it into a presentation to the Atlanta Scala User Group, which I gave in January 2010. The slides from that presentation are here.

05/31/2009 Update: As Mads Andersen pointed out, in the example below, I had the Complex multiplication wrong. As I was working through the example in the book, I typed it incorrectly. I could argue that this blog post was not about my mastery of complex numbers, and was actually meant to show how operator overloading works in Scala, but in the interest of all-around correctness, I have updated the code to contain the proper implementation of complex number multiplication, and I have worked out the examples by hand using the formula on the Wikipedia page to ensure their accuracy. Now, on to the original article.

I’ve been intrigued by Scala for a while now, and I’m finally taking the time to learn it. As I was reading in my book yesterday, I came to the section on operator overloading. Now, this is a topic that developers who’ve been exposed to it feel very strongly about. It’s not quite as rough a discussion as vi vs. Emacs, but it’s close. Some say that operator overloading makes for more elegant code. Some say it just confuses things. I’ve always been in the elegant camp. I think if you can provide operators for your own classes that work intuitively, you ought to be able to do it. In Java, think about how nice BigDecimal would be to use if you had + and – instead of add() and subtract(). Of course, as with anything of power, you have to be careful not to abuse it. It would make no sense to provide a + operator on a Date class, since adding two dates together makes no sense. You have to be smart about it, but having the ability to provide operators for your own classes performing intuitive functions is a good thing.

So as I’m reading the section on operator overloading, it was nice to see that even though you can override the standard mathematical operators, Scala still maintains the proper precedence that everyone is used to. By this I mean that a + b * c will execute the multiplication first, then add the product of b and c to a. The reason this is interesting is because another language that I still love, Smalltalk, does it wrong (or at least, completely differently), and not just for overloaded operators. Smalltalk has no precedence for mathematical operators at all, ever. So a + b * c will execute the + operation on a, passing in b, and then execute the * operation on that result, passing in c. Always. Thus, 2 + 3 * 5 = 25 in Smalltalk, even though it should equal 17. To get 17, you’d have to write the equation as 2 + (3 * 5). I always found that strange.

The canonical example for operator overloading is a class to represent Complex numbers. I will not break with tradition and will, in fact, steal borrow the one from the book. Here, then, is the definition of the Complex class

class Complex(val real:Int, val imaginary:Int) {
    def +(operand:Complex):Complex = {
        new Complex(real + operand.real, imaginary + operand.imaginary)
    }

    def *(operand:Complex):Complex = {
        new Complex(real * operand.real - imaginary * operand.imaginary,
            real * operand.imaginary + imaginary * operand.real)
    }

    override def toString() = {
        real + (if (imaginary < 0) "" else "+") + imaginary + "i"
    }
}

Notice that we have overridden both the + and * operators. They each take another instance of Complex as an argument, do the proper operations and return a new instance of Complex as their result. Just as you would expect. Now, to exercise these operators, we have this

val c1 = new Complex(1, 2)
val c2 = new Complex(2, -3)
val c3 = c1 + c2

val res = c1 + c2 * c3

printf("(%s) + (%s) * (%s) = %sn", c1, c2, c3, res)

val res1 = c1 + c2 * c3 + c1 * c2

printf("(%s) + (%s) * (%s) + (%s) * (%s) = %sn", c1, c2, c3, c1, c2, res1)

Lines 5 and 9 are the interesting parts. The result of running these statements looks like this

(1+2i) + (2-3i) * (3-1i) = 4-9i
(1+2i) + (2-3i) * (3-1i) + (1+2i) * (2-3i) = 12-8i

which is exactly what you’d expect.

Now, C++ people are probably saying, “But C++ has always done it right!” Indeed. But languages like Smalltalk and Scala are far more fun to work in.

Georgia Republican Wants Obama to Make 2010 Year of the Bible

From FOX News comes this little gem Georgia Republican Wants Obama to Make 2010 Year of the Bible. According to the article, GA Representative Paul Broun has introduced a resolution calling on President Obama to declare 2010 the “Year of the Bible.”  The article makes the point that the great Ronaldus Magnus already did this back in 1983, so I guess it’s not completely unheard of. Still, this strikes me as somewhat silly and a waste of Rep Broun’s time.

A bit of the resolution reads

“The president is encouraged … to issue a proclamation calling upon citizens of all faiths to rediscover and apply the priceless, timeless message of the Holy Scripture which has profoundly influenced and shaped the United States and its great Democratic form of government, as well as its rich spiritual heritage, and which has unified, healed and strengthened its people for over 200 years.”

He wants “people of all faiths” to “rediscover” the Bible. I wonder how he would react if some other representative offered up a resolution calling upon Obama to declare 2010 the “Year of the Koran” and asked “citizens of all faiths to rediscover the priceless, timeless message of the Holy Koran.” I doubt he’d support that one. Yes, you could argue that the Bible did influence our founding fathers and that the Koran did not, but still. Calling on people of “all faiths” to read your holy book has a name. It’s called proselytizing.

When One Job Ends, Another Begins

In April of 2008, the owner of the company I worked for told me that he was, effectively, shutting down the company and that I needed to find a new job by June. I was not happy. Over the previous 3.5 years, I had been the entire tech department, I had built every piece of software the company had, and I was extremely emotionally invested in the company. I started looking at opportunities and chased several opportunities, but none panned out.

Ironically, the company I was leaving was an online job search company…

Finally, I contacted an old friend to see if his company had any opportunities. They did, and I interviewed with the team the following week. It was a *six hour interview*, during which my friend stayed out of it, to keep any personal bias from influencing the team. A few days later, they made an offer, which I accepted. Did I mention the *six hour interview*?

I’ve been with them for nearly a year and I can honestly say it’s the best fit in a job I’ve ever experienced. While I enjoyed working completely alone, as I had done for the previous 3.5 years, the team I have joined is the best, and smarted, I’ve ever seen.

Looking at it now, my previous company closing was really the best thing that could have happened to me.