This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Frequently Asked Questions - Programming


There are two ways for simple integer loops:

for (i <- 1 to 1000000) { ... }

or

var i = 1;  while (i <= 1000000){ ...; i += 1 }

Both are fine, but in the current implementation the second one should be more efficient.

Use try and catch, where the catch clause is a pattern match.

   try { 
   // ... 
   } catch {
     case ioe: IOException => ... // more specific cases first !
     case e: Exception => ...
   }

Compile-time checking of exceptions sounds good in theory, but in practice has not worked well. Programmers tend to write catch clauses that catch too many exceptions, thus swallowing exceptions and decreasing reliability.

These keywords are not included in Scala 2.7, and must be implemented in a different way. For break, the simplest thing to do is to divide your code into smaller methods and use the return to exit early. For continue, a simple approach is to place the skipped-over parts of a loop into an if.

Scala 2.8 will include break, but not continue.

 

  1. You can do pattern matching on it,
  2. You can construct instances of these classes without using the new keyword,
  3. All constructor arguments are accessible from outside using automatically generated accessor functions,
  4. The toString method is automatically redefined to print the name of the case class and all its arguments,
  5. The equals method is automatically redefined to compare two instances of the same case class structurally rather than by identity.
  6. The hashCode method is automatically redefined to use the hashCodes of constructor arguments.

Most of the time you declare a class as a case class because of point 1, i.e. to be able to do pattern matching on its instances. But of course you can also do it because of one of the other points. The code example below makes use of two of the characteristics of case classes:

  1. Instances are created without resorting to the new keyword (point 2), for example in
    List(MyInt(1), MyInt(2), MyInt(3))
    
  2. Constructor arguments are accessed from "outside" using the automatically generated accessor functions (point 3), in
    else m.asInstanceOf[MyInt].x == x;
    

 

In Scala private values that evaluate to a constant known at compile-time are turned into private static final Java variables. This undocumented feature should do the trick for you. Just check out the implementation of lists in Scala (see e.g. src/scala/List.java). Both classes :: and Nil have a field serialVersionUID of the following form:

private val serialVersionUID = <numeric literal>;

You can use any value for the numeric literal or you can do it the Java way and use serialver for that purpose. If you want to add such an ID to a class or trait named mypackage.Foo, you would call serialver in the following way:

> serialver mypackage.Foo$class

For a top-level object mypackage.Obj you write:

> serialver mypackage.Obj$

Unlike Java, Scala has relative package names. For instance, you could write

package com.mycompany.tools;
  import mycompany._;
  // ..

which would import everything in package com.mycompany. The problem is that the import statement

  import scala.collection.mutable.ArrayBuffer

then also looks in your package scala, not the global one which is further outside, in the hierarchy.

The advantage of this scheme is that package names need not be absolute, therefore they can be shorter, and more easily adapted when you move things from one package to another.

You can still use an absolute package name in Scala, however, by simply prepending your package name with the special _root_ path, as follows:

import _root_.scala.collection.mutable.ArrayBuffer

The ::: operator is already used for List concatenations, like in List(1,2,3) ::: List(4,5,6) gives List(1,2,3,4,5,6).

Also, we had to make a choice on which operators become right-associative. We chose that everything that ends in a ":" would be so, which means that a ::: b ::: c is translated to method calls c.:::(b).:::(a). Since streams are usually infinite, it would not make much sense to use right-associative operations in this way, so one would need to use another character as the last character, for example ::+

Currying per se does not have a performance penalty. If f and g are methods defined as

  def f(x: Int)(y: Int) = expr
  def g(x: Int, y: Int) = expr

then f(x)(y) and g(x, y) are compiled into exactly the same code.

 

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland