Showing posts with label scala. Show all posts
Showing posts with label scala. Show all posts

Dec 3, 2009

Infinite Lists in Scala

One of the pretty cool things about Haskell is the ability to have infinite lists, thanks to Haskell's laziness. You can create a list containing all the Fibonacci numbers, or all the digits of π, or something like that.

Turns out that Scala can do it too, despite not being a lazy language. The main way to do it is with the lazy keyword:
lazy val hello = epicCalculation()

if (some condition){
println(hello) // epicCalculation() is done here
}else{
// don't use hello
// in this execution path, epicCalculation is never called
}
Here we're creating a constant variable called hello and only using it in one of our if branches. That means that if execution never goes into our if block, then the epic calculation is never computed. Pretty handy sometimes! This example isn't great because we can just call epicCalculation inside the if block, but whatever.
Unfortunately one catch is that the variable is evaluated when you pass it to another function, regardless of whether it is used or not:
object Main{
def getValue = {
println("getting value")
5
}
def output(y : Any) = {
println("outputting")
}
def main(args : Array[String]){
lazy val x = getValue
output(x)
}
}
Even though the variable y is not actually used inside output(), the value of x is still evaluated. So it isn't true laziness, but whatever.

We can also build infinite lists using the Stream class. Here's an example of generating a familiar list of numbers (I'd use Fibonacci but it is a bit more complex since each element depends on two previous elements instead of one):

object InfLists extends Application{
def numbers(current : Int) : Stream[Int] =
Stream.cons(current, numbers(current * 2))

// print out 10 numbers, starting with 1
numbers(1).take(10).foreach(println)
}
Yet again another trivial example, but it is kinda neat to be able to do this.

Note that the following does not work:
println(numbers(1) take 10)
Why not? Well here, we're not actually evaluating the values for the first 10 numbers. So when println goes to print the list, it just prints the first element followed by a ?, because it doesn't know what the rest of the list is.

Now if you actually want the Fibonacci series, you can do it like this:
Stream.cons(1, Stream.cons(1, fib.zip(fib.tail).map(f => f._1 + f._2)))
Swiped from here, converted to Scala. If you zip something with its tail, then you get a list of pairs that look like this: (ai, ai + 1). Then if you map that using +, you'll get your result.

Nov 18, 2009

Using sdljava with Scala

After fixing up sdljava, I decided to try it out with Scala. Turns out it works really well!

Here is the code to get a simple window that closes when you click the close button:
import sdljava.SDLMain
import sdljava.video.{SDLVideo, SDLSurface}
import sdljava.event._

object SDLTest{
def main(args: Array[String]){
SDLMain init SDLMain.SDL_INIT_VIDEO

try{
var framebuffer = SDLVideo.setVideoMode(800, 600, 32, SDLVideo.SDL_HWSURFACE)

var ev : SDLEvent = new SDLQuitEvent()
var loop = true

while (loop){
if ((ev = SDLEvent.pollEvent) != null){
if (ev.isInstanceOf[SDLQuitEvent]){
loop = false
}
}

Thread.sleep(1)
}
}finally{
SDLMain.quit()
}
}
}
This looks almost exactly like it does in C (I probably code Scala/Java with a C accent anyway). I might decide to start adding stuff to sdljava so that you don't have as much boilerplate as you do here, or I could even add in some Scala-only stuff to bind functions as callbacks or something. But I probably won't, sorry...

Anyway the hard part is actually getting this junk to compile. If you check out my sdljava repo here you can grab all the files needed for compiling and executing provided you're running 64-bit Linux, otherwise you'll probably have to download and compile the library yourself.
Drop those into the same folder as your Scala file, and do this to compile:
scalac -cp ./sdljava.jar MyFile.scala
That should work fine (if your code doesn't have any errors). The more annoying part is getting it to actually execute. Unfortunately it seems like when you use the actual scala program, it does not pass parameters to java. So you have to call java directly:
java -Djava.library.path=. -cp /path/to/scala/lib/scala-library.jar:./sdljava.jar:. MyClass
This is because sdljava uses native libraries which are not looked for in the classpath, you need to pass them in the java.library.path variable. Scala does not pass this to java when it is executed, so you have to call java manually.

Anyway, this should get you started to whatever SDL program you want!

Nov 17, 2009

Learning Scala: Euler's Method

I've been messing around more with Scala to see some of its more interesting features, two of which are pattern matching and currying. These are really handy in certain situations, and I decided to share them with you today.

The example I'm using is the Euler method for approximating a solution to a differential equation. This is probably not the most intuitive way of doing the Euler method, but it uses a lot of Scala's interesting features and I think it is a good way of illustrating them.

The Euler method works like this. You have a differential equation in the form y' = f(x, y) and an initial value (x0, y0). You calculate the slope at the initial value, which is f(x0, y0). You then take a step of size h in the x-direction following the slope, which brings you to (x0 + h, y0 + h * f(x0, y0) ). This becomes your new point, and you repeat until you are satisfied with the results. A smaller h will lead to more accurate results, but with more computation.

Here is the not-so-intuitive code:
object Euler{
def main(args: Array[String]){
// Use the differential equation y' = x^2 + y^2
val my_de = solve_de((x, y) => Math.pow(x, 2) + Math.pow(y, 2)) _

// Use a step size of 0.1, and do 10 steps
val generator = my_de(0.1, 10)

// try with different initial conditions
println(generator(0, 1))
println(generator(1, 1))

// create another generator with a smaller step size
val precise_generator = my_de(0.05, 20)
println(precise_generator(0, 1))
println(precise_generator(1, 1))
}

def solve_de(func: (Double, Double) => Double)(step : Double, iterations: Int)(x_0: Double, y_0: Double) =
(List(List(), List(x_0, y_0)) /: (0 until iterations))((s, i) => s match {
case List(res, List(x, y)) => {
val fxy = func(x, y)
List(res ::: List(fxy), List(x + step, y + step*fxy))
}
}).head

}
Look first at the definition for solve_de. It has three argument lists! One of them takes a function of type (Double, Double) => Double, also known as a function that takes two Doubles and returns a Double. The second takes a Double and an Int, and the third takes two Doubles.
The first parameter list takes a function representing the differential equation we are approximating, the second takes the parameters for the approximation which are the step size and the number of steps we take, the third takes the initial values.

If you look back at the main function, you'll see that we call solve_de with only one of its argument lists, and a _ at the end! This is called currying - it returns a new function with the first parameter list filled out. We save this as our variable my_de (note we use val, so this variable is immutable) which is a solution generator for our specific differential equation described above. You use the _ at the end to tell Scala that you are only partially applying the solve_de function.

Next, we call my_de with the values 0.1 and 10. This creates another function which solves our differential equation using a step size of 0.1 and 10 steps. We can then call this function with different initial conditions to get different solutions to the differential equation. Each time we call it, it returns a list of 10 points that lie along our solution curve. If we wanted to, we could then plot this curve using some graphing library.
Note: for some reason here you don't have to call my_de with the _ at the end, it is probably for some reason that I do not yet understand.

After that, we create a more precise generator with half the step size. I double the number of steps so that if we were to graph this alongside the first list, they would have the same range of x-values.

The next bit is the solve_de function, which illustrates some of the more interesting features of Scala. First one (which probably isn't that interesting) is that there are no curly brackets around the body of solve_de. If you have a function in Scala that is only one line, you can just write:
def foo(x) = ...
You don't need to include curly brackets.
We have a fold using the /: operator. If you've used inject() in Ruby then you'll know what I'm talking about, otherwise take a look here for a description of what fold (aka reduce1) is. In Scala you can write this:
(0 /: myList)(some function f)
This does a left fold of myList with the initial value 0, using the function f - aka f(f(0, myList[0]), myList[1])....
The initial value is a list that looks like this:
[ [], [x0, y0] ]
The first element of this list is where we will be sticking the approximated values, the second element is our current point.
We fold this list into (0 until iterations), which is a range equivalent to 0..(iterations - 1) in Ruby. This is a very interesting piece of Scala, because it shows some of the fancier features. Scala is a pure object-oriented language so the 0 there is actually an object of class Int. Effectively what we are doing is calling 0.until(iterations), which returns a Range object that we can use fold on. In Scala for a method which only takes one argument, you don't need to put the . or the brackets.
However there is no until() method for Int. Where does this until() come from? Scala has a feature called implicit functions, which are used for implicitly converting one type into another - like the auto-boxing between int and Integer in Java. Little do you know, there is actually a class called RichInt which supplies the until() method, and a bunch of other handy things (you could write 0 to 5 if you like). When you call until() on 0, Scala first looks to see if Int has an until() method. Since it doesn't, it checks to see if there is an implicit conversion for Ints into a class that does have an until() method. Since there is only one such class (RichInt), it automatically replaces your statement with something like toRichInt(0).until(iterations). If there were more than one implicit conversions however, then Scala would give you a compile error and you would have to explicitly provide your conversion. The main difference between this and auto-boxing in Java is that you can provide your own implicit conversions between any classes you like, provided they don't result in ambiguities.

The next step is to provide a function to the fold operator to use for folding. After the => we see
s match {
This matches the variable s (the "accumulator") against a set of patterns. This is another feature of Scala called pattern matching. This example doesn't really do it justice since we only have one pattern here, and it is just so that we can have a nice way of extracting the variables out of s without using head() and tail(). I think I might post something more detailed on pattern matching in the future. Anyway, we use the expression List(res, List(x, y)) to match s, and this extracts out our current accumulated values as res, and the current position into x,y. We can then compute f(x, y) and put it in fxy (this is to save some time in computation) and then return:
[ new res, [ x + step, y + step * f(x, y) ] ]
The new res value is just res with f(x, y) stuck on the end (that's what the ::: operator does, it concatenates two lists).

Two small syntactic things to note:
- There is not a single semicolon in this program. Scala doesn't need the semicolons at the end of lines, although you can include them if you like.
- There are no return keywords in this program, even though we have functions. Scala doesn't require the return keyword, it will insert it where it thinks you are trying to return something.

So I'm not sure if I'd recommend you actually write Euler's method like this, instead you would probably write it something like this in Scala:
def solve_de(func: (Double, Double) => Double)(step : Double, iterations: Int)(x_0: Double, y_0: Double) = {
var x = x_0
var y = y_0
var res = List[Double]()

for (i <- 0 until iterations){
val fxy = func(x, y)
x = x + step
y = y + step * fxy
res = res ::: List(fxy)
}
res
}
However in this case, you wouldn't be able to use all those fun little toys that Scala gives you, so I did it in a different way.

1In Scala fold and reduce are two different things: fold takes an initial element, where reduce uses the first element of the list as the initial element. Reduce will throw an exception if used on an empty list, where fold will just return the initial element. In non-Scala languages, reduce and fold are the same thing.

Oct 7, 2009

Multiple Inheritance in Scala vs. C++

I've made an interesting discovery today on how Scala's type system is slightly more awesome than C++'s type system. It has to do with traits.

There's a C++ project I'm working on where I'm pulling out some shared functionality from a few classes and putting it into another class that will be used like a mixin (one reason to learn a language with mixins - you get better ideas when you go back to languages that don't have them). It's fairly simple: I have a base class Creature, and I have a number of classes which inherit from Creature to define some specific behaviour. Two examples are Giraffe and Tiger. These two subclasses have very different habits when it comes to how they find their food, however there's some basic functionality involved in the mechanics of eating and starvation and stuff that is common. So I put that basic functionality into a class called Hungry:
class Hungry{
...
public:
void act();
};
In the act() method, it makes the creature slightly more hungry and if it is too hungry, it makes the creature die. Unfortunately, the Hungry class has no idea what die() is. So I could have Hungry inherit from Creature as well, however that will cause diamond problems when we start getting into many different traits for different creatures. The next step was to try putting die() as a pure virtual method in Hungry. Unfortunately that didn't work unless I explicitly defined die() in both Giraffe and Tiger, which would be annoying since die() is specified in Creature and works just fine. With that, the code ends up like this:
class Hungry{
...
public:
...
void act() {
if (--hunger <= 0)
die();
}

virtual void die() = 0;
...
};

class Giraffe : public Creature, public Hungry{
...
void die() { Creature::die(); }
...
};
This is really a minor detail, but slightly annoying. Shouldn't it be able to figure out that there is one concrete implementation of die() in Giraffe and Tiger?

Turns out that in Scala, it does figure this out:
class Creature{
def die(){
...
}
}

trait Hungry{
def act() = {
hunger -= 1
if (hunger <= 0)
die
}

def die // abstract method

var hunger : Int = 0
}

class Giraffe extends Creature with Hungry{
override def act() = {
super[Hungry].act
}
}
This works perfectly. It is type-safe too, if you remove the "extends Creature" from Giraffe, it will give you an error saying that you haven't defined die.

I'm confused, why can't C++ do this? This doesn't really have anything to do with the fact that Scala is using a trait, because if you made Hungry into a class and allowed Scala to inherit from multiple classes, it wouldn't be any different. The fact of the matter is that Giraffe and Tiger do have a die() method, but the C++ compiler isn't recognizing this and saying that they are abstract classes.

Oct 6, 2009

Multiple Method Inheritance in Scala

I had a little issue today that likely crops up once in a while when using Scala's traits. I have a class with a particular method foo(), and a trait with a method of the same name. When I created a derived class that used this trait, I didn't know how to specify which version of foo() I wanted to call. Let's take a look at our picture:
class Blah{
def foo(){
}
}

trait Tleh{
def foo(){
}
}

class Dingle extends Blah with Tleh{
override def foo(){
super.foo // this calls Tleh.foo
}
}
As I mentioned in the comment there, using super.foo calls the trait's version of foo(). But what if you want to call Blah's version of foo()?

It's actually pretty simple, and a bit intuitive if you know a bit of Scala:
class Dingle extends Blah with Tleh{
override def foo(){
super.foo // calls Tleh.foo
super[Blah].foo // calls Blah.foo
super[Tleh].foo // calls Tleh.foo
}
}
This is pretty simple, but it took me a little while to figure it out since there doesn't seem to be any mention of this in the docs I found!

Aug 28, 2009

Interfacing between JRuby and Scala

One of the major features of JVM languages is their interoperability. It's really easy to call Java code from a JRuby script, and (while slightly less easy) you can run a Ruby script from within a Java program.

However, how difficult is it to interface between two non-Java JVM languages? It turns out that it isn't really that hard at all! For this post, we'll talk about how to interface between JRuby and Scala, it's really rather simple.

So here's our scenario. We are writing our main app in Scala, because Scala is faster than Ruby. However there are some situations where we don't want to have to recompile the whole thing to make changes, and we want the code to be nice and easy to understand for people who don't know Scala (admittedly, Scala is not a good first language as it is rather complex). We're going to embed some Ruby scripts within our app.

Here's a basic Scala outline in ScalaTest.scala:
import javax.script._   // import Java's scripting API
import java.io.FileReader

object ScalaTest extends Application {
var engine = (new ScriptEngineManager).getEngineByName("jruby")

engine.eval(new FileReader("test.rb"))
}
And test.rb:
puts "Hello from Ruby!"
Before we attempt to run this though, we'll need to get both JRuby, and the JRuby engine. You can grab JRuby from their website (as of this writing the latest version is 1.3.1), just extract that and grab jruby.jar from the lib folder. As for the JRuby Engine, you'll have to grab the big engine tarball from the Java site and extract jruby-engine.jar from the jruby/build folder. Once you have those put them in the same folder as your code, then compile and run:
scalac ScalaTest.scala
scala -cp .:jruby-engine.jar:jruby.jar ScalaTest
What you should see is "Hello from Ruby!" pop up on the screen.

So this is pretty cool, but how do we get information between Scala and Ruby? That part can be a little bit tricky since the type systems in Scala and Ruby are very different. However for our example here, we will stick to simple things. Here is our new Scala code:
import javax.script._
import java.io.FileReader

object ScalaTest extends Application {
val engine = (new ScriptEngineManager).getEngineByName("jruby")

val name = Console.readLine("What is your name?\n")

// assign a variable in the engine
engine.put("name", name)

// cast the result of the execution into a string
val colour = engine.eval(new FileReader("test.rb")).asInstanceOf[String]

Console.print(name + ", your favourite colour is ")

// this part is unnecessary, but let's have some fun with colours :)
Console.print(
if (colour.toLowerCase == "blue")
Console.BLUE
else if (colour.toLowerCase == "red")
Console.RED
else if (colour.toLowerCase == "green")
Console.GREEN
else
""
)

Console.println(colour + Console.RESET + ".")
}
And the Ruby code:
# the name variable is passed in as $name, which is a String
puts $name + ", what is your favourite colour?"
gets.strip
While this is a trivial example, we could use this to embed all sorts of functionality within our application. In fact, this isn't even limited to JRuby. By changing the getEngineByName call to say, "Javascript", we can execute Javascript code instead of Ruby code. Or any other JVM language included in that big engine tarball, including Scheme, Jython, and Groovy to name a few. You can even use Java as a scripting language, although you have to jump through a few hoops since Java doesn't support global variables.

Aug 14, 2009

Actor Simulation Synchronization Issues

A while back I did up a post about using Scala actors in a synchronized simulation. I'm hoping to use this to model a simple economy, however I've run into a major problem and I'm trying to find a solution to it - which is why it took so long for me to write a follow-up to that last post.

The way the other simulation worked is by using synchronized time steps. Normally this is good because it means that actors which take varying amounts of time to process can all finish their job before the next time step starts. This also helps when you decide to scale and use a distributed system, you will end up having slower machines and network delay, but can still maintain synchronization because the faster machines will either do more work, or will wait for the slower machines.

Synchronization in my simulation was done using the Act and DoneAct messages. When an agent receives an Act message, it means that the next time step is starting and that they should begin processing. Then when they are done, they send a DoneAct message to the simulation driver to say that they have finished processing. The problem with this is that some agents may send messages to other agents that are finished. There is the scenario that an agent, A, sends a message to another agent, B, and then A sends the DoneAct message to the simulator. However B may well still be processing away the message, which may in turn affect agent C, which may then wrap around and affect agent A. Effectively this could turn into an infinite loop, and due to the nasty halting problem there is not really any general way of detecting this.

I have a solution, however I am not sure if it will work. Basically agents cannot communicate with one another if they are using the ! approach (asynchronous messaging). They can use the ?! method (synchronous method) where when agent A sends a message to agent B, agent A will wait for agent B to return before continuing execution (basically the same as a method call in traditional OO languages like C++ or Java). However in the case where agent A wants to send an asynchronous message to agent B, it can do so by sending a Delayed() object to the simulator, which will then send the message to B at the next time step.

Basically I'm thinking out loud here, hoping that by explaining things here it might give me some insights on how to go about building this thing. If anybody is interested in this type of thing and wants to give their two cents, feel free to comment :)

Jul 28, 2009

Using Scala Actors and Case Classes

When I posted about actors last month I didn't really provide many code examples. That's mainly because I didn't really know a good actor library for the languages that I like to use. So I decided to dig a bit deeper into Scala to use the built-in actor library. It's pretty good!

So before I get started, I'll describe how it works. You have these classes that inherit from Actor. In these classes you define an act() method. This is similar to the run() method in the Java Thread class.
When an actor receives a message, it goes into the actor's mailbox. You can check the mailbox with the receive() method.

How are we going to represent these messages? Well, a rather convenient approach is to use a feature of Scala: case classes. These are lightweight classes which basically just have a constructor and some public attributes. Kinda like structs from C, but with a constructor and inheritance.

So for my example, I'm coding a basic simulation environment. We want this simulation to be multi-threaded, so that we can take advantage of multiple CPUs in a machine. And we've decided to use Scala actors for it. This will be an agent-based simulation, so we will obviously need an Agent class. We will also have a Simulator class which drives the simulation.

Let's start with two types of messages. For each time step, the Simulator sends an Act message to each Agent. When the agent is done processing, it sends a DoneAct message back to the Simulator saying it is done. Since the number of Agents is fixed, let's just use a counter to keep track of the finished agents.

Here is the Simulator class:
class Simulator extends Actor {
// need to override start to tell all our agents to start as well
override def start() : Actor = {
agents.foreach(agent => agent.start)
return super.start()
}

// something to add agents
def add(agent : Agent) = agents += agent

def act(){
// loop indefinitely
loop {
// check the mailbox
receive {
case Act => {
// this keeps track of how many agents we are waiting for
agents_left = agents.size

// the binary ! operator is what is used to send a message
agents.foreach(agent => agent ! Act)
}
case DoneAct = {
agents_left -= 1

// if we've gotten messages back from all agents, let's start
// the next simulation step
if (agents_left == 0)
this ! Act
}
}
}
}

var agents_left = 0
var agents = new LinkedList[Agent]()
}
Our Agent class:
class Agent(simulator : Simulator) extends Actor {
def act() {
loop {
receive {
case Act => {
// do some actions
simulator ! DoneAct
}
}
}
}
}
This class is a lot simpler, mainly because we haven't actually defined anything to do yet.

For completeness, here are the Event classes:
abstract case class Event()

case class Act() extends Event
case class DoneAct() extends Event
And a main function:
object Sim {
def main(args : Array[String]) {
var simulator = new Simulator()

// add a bunch of agents
simulator.add(new Agent(simulator))
simulator.add(new Agent(simulator))
simulator.add(new Agent(simulator))
simulator.add(new Agent(simulator))

// start the simulator, and send it an Act message
simulator.start
simulator ! Act
}
}
So this simulation is pretty basic. In fact, it's pretty useless. It doesn't actually do anything. However this gives us a framework for creating a simulation. Let's tweak the agent class a little:
abstract class Agent(simulator : Simulator) extends Actor {
def act() {
loop {
receive {
case Act => perform()
}
}
}

def perform() {
// do nothing
}
}
We can now use our Agent class as a base class for other agents. I will end this post now, however next time I will make some subclasses of Agent to actually do something.

May 30, 2008

Adventures in Scala: Part II

My first impressions of Scala: It's different. I have a feeling a lot of Java programmers will hate this language. And it is not a newbie language, I would recommend knowing at least one functional language before tacking this. Preferably one with static-typing, like Haskell or ML.

This is my first experience with a type-inferenced imperative language. In fact, I can't really think of any other type-inferenced imperative languages, since the only languages I can think of that use type-inferencing are functional languages.

The documentation and community around it is still fairly small, as is expected. The tutorials on their site seem to be more oriented toward language features and the differences from Java. This is nice and all, but is there differences in the libraries, for example I/O?

So in trying to learn Scala, my first project was something I did in university in a Java class: build an interpreter for TML (tiny machine language). TML is a simple RISC-style assembly language. There are a few registers (I put 8) and some memory (I put 1024 bytes). You have basic commands like load, add, jmp, etc. and labels to make jumping easier. And there are comments.

The little things I found are this:
  • The difference between var and val. Both are used to declare a variable, but from what I've seen in my short escapade is that variables declared with val are immutable (const).

  • Array syntax: You use parentheses instead of square brackets to do array access. Odd, but not hard to adapt to.

  • Generics: This was a bit more interesting. The square brackets are used to specify the type instead of angle brackets:
    var list = new LinkedList[String]()
    As with the array syntax, this isn't so bad, you just need to adapt to it. However there are some issues with the type inferencing in situations like this:
    var list = new LinkedList()
    In Java, this would default to being a linked list that holds values of type Object. In Scala, this means that the list holds values of type Unit. The Unit type is equivalent to void in C/C++/Java. So this list can only hold the one possible object of type Unit: (). Pretty useless! So you have to specify which type of objects you want in the list, even if that type is Object. Little annoying.

  • Keeps Java standard libraries: So I still have to go
    var input = new BufferedReader(new FileReader(stdin))
    when I want to read input from the console. At least I don't have to put try..catch around it. So it's slightly less annoying than Java. Note that I did try to look around a bit to see if Scala made this easier, but I couldn't really find anything. Might just be that I'm lacking Google skills.

  • Complicated: It has a lot of Java's features, plus a ton more. Singleton classes, case classes, functional-type things, etc. Not sure if this is a good thing or a bad thing, but we'll see.
So far, the language is a huge improvement on Java, but still too Java-like for me to really love the language. I'll still try and work with Scala, but I find myself still preferring C++ when I need a language with structure.

May 20, 2008

Adventures in Scala: Part I

I am attempting to learn at least one new language a year and one of them this year is Scala. It is a multi-paradigm language that pretty much just takes Java and modernizes it. By that I mean it adds functional-style ways of doing things, like lambda statements, type inferencing, and gives it a much prettier syntax.

This article is about how to install Scala on Ubuntu. First off, you need Java installed. Scala programs compile to Java bytecode, which means you need the Java virtual machine in order to run your Scala programs. My advice is to install the sun-java6-jdk package. There are open-source Java implementations, but they suck. The Sun one is much better (the fact that it actually works is my main reason for using it).

Now the next step you might think is to then install the scala package from the Ubuntu repositories. Unfortunately as of today, that version is 2.3, and the most up-to-date one from the Scala pages is 2.7 (UPDATE Dec. 20/09: The version in the repo is 2.7.5 now, which is still not the latest version). You're much better off just doing this:
wget http://www.scala-lang.org/downloads/distrib/files/scala-2.7.7.final.tgz
tar -zxvf scala-2.7.7.final.tgz
sudo mv scala-2.7.7.final /usr/share/scala
sudo ln -s /usr/share/scala/bin/scala /usr/bin/scala
sudo ln -s /usr/share/scala/bin/scalac /usr/bin/scalac
Now you have a working Scala implementation! Make sure to check the most up-to-date version on their website. I'll try and keep this up-to-date, but I'm only human and only check the Scala website every now and then.

To uninstall:
sudo rm -rf /usr/share/scala /usr/bin/scala /usr/bin/scalac