22 September 2007

Something is rotten in the state Ukraine

Maybe you know, maybe you don't, but Ukraine is approaching another round of parliament elections. As we didn't have enough elections recently! And once again, three major forces participate and again as arrogant and hostile they are, they try to be good now and evince at least some care about Ukraine and Ukrainians:





But look at the pictures, look carefully, look closely. Maybe you'll see what I can't see there. Maybe I'm blind, but what I see is only lots, lots of white, orange and blue flags that belong to our celebrated political parties. And what I don't see is Ukrainian flags! There're none. No flag of the country and people they are so selflessly fighting for.

These pictures alone clearly show how much our parties care about Ukraine... Imagine how many other proofs we have here ;) Do we need these guys in parliament? Several years in a row my answer was "no!". This year I say "stay away from this country!".

Photos are copyright UNIAN. Links: 1, 2, 3

08 September 2007

Funny consequences of "functions are objects" rule in Scala

Sorry for another Scala-related post, but I simply couldn't stand. This language is an unique combination of interesting language features and clear and concise syntax which is so rare in the world of programming languages.

Scala is truly object-oriented. This does mean that everything is an object, even functions. Err, functions you'd ask? Yeah, functions are indeed objects but that wasn't a surprise for me because I've seen and used that in Javascript. But function inheritance indeed was a surprise.

How can that be possible? Martin Odersky gives an example that functions with one argument in Scala are objects that mix1

trait Function1[-A, +B] {
def apply(x: A): B
}

Here "-A" means that function that has AnyRef as an argument inherits a function that has a String argument. Take a look at this magical example: ;)

object MyProg {

def doSmthStr(a: String): Int = a.length
def doSmthAny(a: AnyRef): Int = a.hashCode

def compute(function: AnyRef => int) = {
function("Haha")
}

def compute2(function: String => int) = {
function("Haha")
}

def main = {
// not possible because doSmthStr is of type String => int
// which is supertype of AnyRef => int

compute(doSmthStr)

// possible because doSmthAny is exactly of type AnyRef => int
compute(doSmthAny)

// possible because doSmthStr is exactly of type String => int
compute2(doSmthStr)

// possible because doSmthAny is of type AnyRef => int
// which inherits String => int

compute2(doSmthAny)
}
}

MyProg.main

Isn't that cool, the function doSmthAny with AnyRef (aka Object in Java) argument inherits the function doSmthStr with String argument and therefore can be used whenever we need doSmthStr. Amazing!!!

Even more amazing is when the return types in those functions are different. For a function to be the subtype of another function we not only require its argument to be a supertype, but its return value to be a subtype. Citing "Scala by Example" book, function S=>T2 is a subtype of S'=>T' if S' is a subtype of S and T is a subtype of T'.

1
Traits are the Scala implementation of mixins. For C++ guys mixin is just a multiple inheritance. For Ruby guys trait is more like a module (the difference is that in Ruby you'd "include" the module into your class and in Scala you'd "extend" the class with a trait).

2
S=>T is a function defined as:
def function(arg: S): T

More surprises in Scala: covariance and contravariance

I've been reading more about Scala discovering more and more nice features the modern language with static typing can bring. Some of those features look to me just as an syntactic improvement over what we already can do with another statically typed languages like C++. For example, pattern matching example from my last blog is definitely what you can do with several AST classes (they need to have type() or rtti() method) and your own implementation of visitor pattern in C++.

But there're some language features in Scala I didn't expect and didn't think about before. The perfect example IMHO is covariant and contravariant subtyping I discovered for myself just a couple of days before.

Think about this example, if we have class B that inherits class A then we can use objects of type B whenever we need objects of type A. So far so good. But what if we have template class X with A and B as parameter types? C++ tells us X<A> and X<B> are unrelated:

class A {};
class B: public A {};
template class X {};

int main()
{
B *t1 = new B;
A *t2 = t1; //ok because B inherits A

X<B> *x1 = new X<B>;
//error!!! because C++ has non-variant subtyping
// so X<B> and X<A> are different types
X<A> *x2 = x1;
}

Contrary to that, in Scala you can declare that X[B] inherits X[A] and have covariant subtyping or even declare that X[B] inherits X[A] and have contravariant subtyping:

class A {}
class B {}
class X[+Type] {} // +Type means "covariant"

val t1 = new B
val t2 = t1 // ok, B inherits A

val x1 = new X[B]
val x2 = x1 // ok too because X[B] inherits X[A]

return


Not that some elements of covariance and contravariance of types didn't exist before in familiar languages like C++ and Java. Contrary to that they did, but most likely I woulnd't have learned about them if I didn't start learning Scala which directly exposes those things as language features. Cool language Scala is... I must say, very cool ;)