GIGO: words unreadable aloud
Mishrogo Weedapeval
 

 

  Sunday 2 May 2004
Chapter 2, Exercises 1-6, Thinking in Scala

Here's a start at a Scala version of a selected subset of the examples from Bruce Eckel's Thinking in Java.

In my usage, I typically prepend a "package x;" statement (yep, literally "x") in order to keep the generated .class files out of my current directory. But in future blog entries, I'll likely omit the package lines, until such time as we're really looking at packages. If I get that far.

I've renamed as many classes and objects as made sense to me, to have names that indicate the chapter number and example number. Like the author of THECLAPP, I use zsh. I've never messed with the completion control stuff, and the fact that I put all of my example classes into the "x" package makes these commands less necessary, but here are the zsh commands to make the tab-completion work better for scala:

compctl -g '*.scala' scalac
compctl -g '*.class(:r)' scala
compctl -g '^*.class' vi gvim

I'm currently using Scala version 1.1.1.0 on Mac OS X (10.3, i.e., Panther). Use commands like the following to compile and run the examples:

scalac c2x2.scala
scala  x.c2x2

Here are exercises 1 through 6 from chapter 2, corresponding to the first couple of entries from THECLAPP.

Chapter 2 Example 1

package x;
object c2x1 {
    def main ( args: Array[String] )  = {
        Console.println( "Hello, world" );
    }
}

Note that c2x1 is an object, not a class: From the scala language reference manual, section 5.4.1: Classes in Scala do not have static members; however, an equivalent effect can be achieved by an accompanying object definition.

Chapter 2 Example 2

You could actually give the class (c2x2c here) the same name as the module-level object, but then you couldn't run it as main, because scala appears to look first for a main method in the given class, before it looks for one in the object. Which is weird, since main has to be static and scala classes do not have static members. Anyway, this works for me:
package x;
class c2x2c {  };
object c2x2 {
    def main ( args: Array[String] )  = {
        val x = new c2x2c;
    }
}

Chapter 2 Example 3

The obvious translation is illegal in scala:
c2x3.scala:5: class DataOnly needs to be abstract, since variable i in class DataOnly is not defined (Note that variables need to be initialized to be defined).

To get it to compile, I made the additions shown in red:

package x;
// DataOnly.scala
// chapter 2, exercise 3 
class DataOnly {
    var i : Int = _;
    var f : Float = _;
    var b : Boolean = _;
}
object c2x3 {
    def main ( args : Array[String] ) = {
        var d = new DataOnly;
        d.i = 47;
        d.f = 1.1f;
        d.b = false;
    }
} 

The underscore is a type-specific "default value".

Chapter 2 Example 4

Not really anything new or surprising here, except to note that System.out is forwarded to a shorter and more convenient name in Scala.

package x;
// DataOnly.scala
// chapter 2, exercise 3 
class DataOnly {
    var i : Int = _;
    var f : Float = _;
    var b : Boolean = _;
}
object c2x4 {
    def main ( args : Array[String] ) = {
        var d = new DataOnly;
        d.i = 47;
        d.f = 1.1f;
        d.b = false;
        Console.println("d.i is " + d.i);
        Console.println("d.f is " + d.f);
        Console.println("d.b is " + d.b);
    }
} 

Chapter 2 Example 5

For c2x5, note that the method "storage" does not require {} nor return. Scala is an expression-oriented language. There are still statements, but most of them are declarations (var, val, class, trait, object). Even "if" and "while" are function calls.

Scala could have defined "length" to be a method that would get called without requiring the parentheses. And note that I could have omitted the return type declaration for the "storage" method: scala's type system could infer that from the type of String.length.

class UseStorage {
    def storage ( s : String ) : Int = s.length() * 2;
}
object c2x5 {
    def main ( args : Array[String] ) = {
        val s = new UseStorage( ).storage( args(0) );
        Console.println( "storage for \"" + args(0) + "\" is " + s );
    }
} 
Also note that array access in Scala uses parentheses, not [square] brackets. Brackets in Scala are pretty much restricted to generic types and their instantiations.

Chapter 2 Example 6

Classes in Scala still do not have static members; so this looks a little different. And I took the liberty of printing out the value before and after the incr call. And note that the incr call does not require parentheses.
object StaticTest {
    var i = 47;
    def pri ( s : String ) = {
        Console.print( "StaticTest.i " + s + ": " );
        Console.println( i );
    }
}
object StaticFun {
    def incr = { StaticTest.i = StaticTest.i + 1; }
}
object c2x6 {
    def main ( args : Array[String] ) = {
        StaticTest.pri( "before" );
        StaticFun.incr;
        StaticTest.pri( "after" );
    }
}


Whew. Putting all that into Radio UserLand's HTML-Lite form took longer than I thought it would.
4:06:06 PM   comment/     



Click here to visit the Radio UserLand website. Click to see the XML version of this web page. © Copyright 2007 Doug Landauer .
Last update: 07/2/6; 12:38:51 .
Click here to send an email to the editor of this weblog.

May 2004
Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Apr   Jun

Previous/Next