A Concise Introduction to Scala
Copyright ©2010, David Matuszek

Classes
Console I/O
Data Types
Declarations
File I/O
General
Identifiers
Input/Output
Methods
Objects
Program Structure
Running Scala
Scripts
Statement Types
Traits

General

Running Scala

In a Java application, you need a public static void main(String[] args) method. In a Scala application, you need a def main(args: Array[String]) method.

How to run Code Results/Comments
On the command line as a REPL (Read-Eval-Print-Loop).
dave% scala
Welcome to Scala version 2.7.7.final (Java ↙ HotSpot(TM) 64-Bit Server VM, Java 1.6.0_17). Type in expressions to have them evaluated. Type :help for more information. scala> 2+2 res0: Int = 4 scala> exit

No main method is required in this case.

 

As a script.
println("Hello from a script.")
dave% scala HelloScript.scala
Hello from a script.
Scala automatically wraps your lines in a class and a main method, so don't do this yourself.
As a shell script.
#!/usr/local/share/bin/scala
println("Hello from a script.")
This is the correct location for Scala on my Mac, but it doesn't work for me. (Should try it on UNIX and Windows).
As an application.
object HelloApp extends App {
  println("Hello, World!")
}
dave% scalac hello.scala
dave% scala HelloApp
Hello, World!
File name doesn't have to be the same as the application name. The App trait wraps your code in a main method.
As a single object.
object HelloObject {
  println("In object")
  
  def main(args: Array[String]) {
    println("In main")
  }
}
dave% scalac HelloProgram.scala
dave% scala HelloObject
In object
In main
As a program.
class HelloClass {
  def inClass() {
    println("In class")
  }
}

object HelloObjectPlusClass {
  println("In object")
  
  def main(args: Array[String]) {
    println("In main")
    val c = new HelloClass
    c.inClass()
  }
}
dave% scalac HelloWithClass.scala
dave% scala HelloObjectPlusClass
In object
In main
In class

The object may not have the same name as the class!

scalac is the compiler. You can use fsc instead, which remains in memory and so is faster (after the first use).

Identifiers

Scala has four types of identifiers:

Alphanumeric identifiers:
Operator identifiers:
Mixed identifiers:
Literal identifers:

Declarations

All variables must be declared, with either var (if the value may change) or val (for constants). In Scala, val is preferred, unless you have good reason to use var. If given an initial value in the declaration, the variable's type is inferred and need not be explicitly stated (but it may be). If explicitly stated, the type comes after the variable and a colon, for example, var q: Boolean = true.

The types of variables must be declared:

Type parameters (generics) are enclosed in square brackets, for example, Array[Int].

Within a method, variables must be given an initial value. Variables within a class (and not within a method) may optionally be given an initial value.

When initial values are not given, new is required: val ary = new Array[Int](5)
    and default values of zero, false, or null are used.
When initial values are given, new is not allowed: val ary2 = Array(3, 1, 4, 1, 6)

The type of a function is written with the double-headed arrow, => or the Unicode version, . Except in the case of a single argument, parentheses are required:

Data types

Scala has no primitives, only objects.

Strings

A String may be enclosed in double quotes, "...", or in triple double quotes, """...""". The latter is a raw string (that is, \ does not "escape" characters) and may contain newlines.

A Symbol is an interned string. A symbol literal starts with a single quote, ', followed by a letter, then zero or more letters and digits.

Lists

Lists are the most valuable data type in any functional language, including Scala.

Much of the following information is from http://anders.janmyr.com/2009/10/lists-in-scala.html.

Lists are:

When it is necessary to specify the type of a list, write it as List[Type]. A literal list is written as List(value, ..., value).

Fundamental (efficient) list methods are:

Functions defined in terms of the above include:

Higher-order functions on lists

Tuples

A tuple consists of from 2 to 22 comma-separated values enclosed in parentheses. Tuples are immutable. To access the n-th value in a tuple t, use the notation t._n, where n is a literal integer in the range 1 (not 0!) to 22. There may be a spaces around the dot, but not between _ and n.

Expressions

If expressions

The value of the if expression is the value of the expression that is chosen; or, if no condition is satisfied and there is no else clause, the value is the Unit value, ().

For expressions (known in other languages as list comprehensions)

The for expression is used to create and return a list. The syntax is for (seq) yield expression, where:

Examples:

Match expressions

Syntax:

variable match {
    case value1 => expression1
    case value2 => expression2
    ...
    case _ => expressionN
}
The match expression uses pattern matching to select a case, then the value of the match expression is the value of the corresponding expression. It is an error if there is no matching case; case _ will match anything.

Statement types

Statements return the Unit value, ().

Syntax Example Comments
var name: type = value var abc = 5 Variables must be given initial values, except when within a class.
var name: type var abc: Int Allowable within a class.
val name: type = value val five = 5 val declares a constant, which must be given a value; explicit type information is allowed but redundant. A val name for an object is constant in the sense that the name cannot be reassigned; but the contents of the object may be modified.
name = expression abc = 10 Values may be assigned only to var variables.
name += expression abc += 1 All the various op= operators are allowed. ++ and -- do not exist in Scala.
if (condition) expression
else if (condition) expression
else expression
if (x < 0) {
    println(x)
    x = -x
}
else x = x + 1
Zero or more else if clauses may be used, and the final else is optional. As in Java, braces should be used to group several statements into a single statement.
while (condition) statement
var x = 1
while (x < 1000)
    x *= 2
Nothing unusual to note. However, Scala has no break or continue statements.
do { statements } while (condition)
var x = 1
do { x *= 2 }
while (x < 1000)
    
Nothing unusual to note. However, Scala has no break or continue statements.
for (variable <- list) statement
for (x <- ary)
    println(x)
The parenthesized expression may contain tests, assignments, and additional generators (variable <- list expressions).
for (variable <- min to max) statement
for (i <- 1 to 10)
    println(i)
to is a method of RichInt. to is inclusive; until excludes max.
for (variable <- min to max if condition)
statement
for (i <- 1 to 15 if i % 2 == 0) print(i) for comprehensions may have guards.
variable match {
    case value1 => statement1
    case value2 => statement2
    ...
    case _ => statementN
}
choice match {
    case true => println("Yes")
    case false => println("No")
    case _ => println("Maybe?")
}

Cases are tried in order; the _ matches anything, so if used, it must be last. break is neither necessary nor allowed.

Types may be matched, as:
case var: type => statement

     
     
     

Methods

Syntax:

access may be private, protected, or public by default.

The return type of a method can usually be omitted; it must be declared:

For reasons of clarity, it is usually best to declare the return type.

Braces around the body may be omitted if the body consists of a single expression, whose value is to be returned.

Methods may be overloaded, as in Java.

Inherited methods may be overridden, in which case the method definition must be preceded by the keyword override.

Function literals

Syntax: (arg1: Type1, ..., argN:TypeN) => expression

Passing function literals as arguments

Within an enclosing argument list, the parentheses around the parameter list can usually be omitted.
Example: "aBcDeF".map(x => x toLower)

If each parameter is used only once, and the parameters appear in the expression in the same order as in the parameter list, the parameter list may be omitted, and underscores may be used in the expression.
Example: "aBcDeF".map(_ toLower)

Program structure: Classes, Objects, Traits and Scripts

Scripts

A script is a list of commands that can be interpreted directly by the Scala system. Scala wraps the script in a main method and executes it immediately. The syntax for running a script is simply scala myScript.scala.

Classes

A class describes objects, as in Java. A class may extend one other class, and it may include any number of traits. A class has a primary constructor, which is part of the class declaration itself.

class Foo { ... }
By default, a class extends AnyRef.
class Foo(name: String) { constructor_body }
The primary constructor is part of the class header. Parameters are put after the class name, and the constructor body is the entire class body.
class Foo(a: Int, var b: Int, val c: Int) { ... }
Constructor parameters are handled as follows. Automatically, all parameters are automatically declared as private fields; a has private getters and setters; var b has public getters and setters; and val c has a public getter. A setter method for a parameter v has the name v_=.
def this(parameters1) { this(parameters2); ... }
Auxiliary constructors are defined with this, and can call the primary constructor.
class Foo(a: Int, b: Int) extends Bar(a + b) { ... }
When extending a class, any base class (=superclass) parameters are provided immediately.
class Dog(name: String) extends Animal with Friend { ... }
A comma-separated list of traits can follow the keyword with. Any uninitialized vars and vals defined by the trait must be initialized by the class.

Objects

In addition to creating objects from classes, you can declare objects. An object is declared like a class, but with the keyword object instead of class; also, an object cannot take parameters. Whereas a class declaration describes a blueprint for objects, an object declaration declares a single object.

A program, other than a script, must contain an object with a main(args: Array[String]) method.

When you define a class and create objects from it, you use the keyword new:

scala> class Dog(name: String)
  defined class Dog

scala> val a = new Dog("Fido")
  a: Dog = Dog@a80370d
But when you create an object "literal", you don't use new:
scala> val t = Tuple(1, "apple")
t: (Int, java.lang.String) = (1,apple)

scala> val l = List(1, "apple")
l: List[Any] = List(1, apple)

scala> val s = Set(1, "apple")
s: scala.collection.immutable.Set[Any] = Set(1, apple)

Traits

Traits are declared like classes, used like Java interfaces, and may contain fully-defined methods.

Input/Output

Console:

val data = readline // Reads a single line from the Console

print(data)         // Prints to the Console without a newline

println(data)       // Prints to the Console with a newline

Files:

import scala.io.Source, scala.io.Source._

val chooser = new FileChooser
val result = chooser.showOpenDialog(null)
val file = if (result == FileChooser.Result.Approve) Some(chooser.selectedFile) else None
val fileName = Some(file)

for (line <- Source.fromFile(fileName).getLines) { dump(line) }

val lines = Source.fromFile(fileName).getLines.toList

GUI Programs

Here is a template for a GUI program:

import scala.swing._
import event._

object SampleGUI extends SimpleGUIApplication {
  def top = new MainFrame {  // top is a required method
    title = "A Sample Scala Swing GUI"
    
    val label = new Label { text = "---------------" }
    val button = new Button { text = "Click me" }
    
    contents = new FlowPanel {
      contents += label
      contents += button
    }
    
    listenTo(button)
    
    reactions += {
      case ButtonClicked(button) =>
        label.text = "You clicked!"
    }
  }
}

MainFrame extends Frame with RootPanel with Publisher. MainFrame includes:

  From Frame From RootPanel From Publisher
Values     listeners
    reactions
Methods contents_=(c: Component): Unit contents : Seq[Component] (at most one component) listenTo (ps : Publisher*) : Unit
title : java.lang.String contents_= (c : Component) : Unit deafTo (ps : Publisher*) : Unit
menuBar_=(m: MenuBar): Unit font_=(f : java.awt.Font) : Unit  

Here are some Components:

Component type Vals and vars Methods
class Button(text0 : java.lang.String)
extends AbstractButton
listeners
reactions
class TextField(text0 : java.lang.String, columns0 : Int)
extends HasColumns
listeners
reactions
class TextArea(text0 : java.lang.String, rows0 : Int, columns0 : Int)
extends HasColumns with HasRows
listeners
reactions
text : java.lang.String
text_=(t : java.lang.String) : Unit
editable_=(x : Boolean) : Unit
class CheckBox(text : java.lang.String)
extends ToggleButton
listeners
reactions
selected : Boolean
selected_=(b : Boolean) : Unit
class ButtonGroup(initialButtons : AbstractButton*)
extends AnyRef
buttons : Set[AbstractButton] select (b : AbstractButton) : Unit
selected : Option[AbstractButton]
class ComboBox[A](items : Seq[A])
extends Component
listeners
reactions
object selection extends Publisher
class MenuBar
extends Wrapper
contents
listeners
reactions
class Menu(title0 : java.lang.String)
extends MenuItem with Wrapper
contents
listeners
reactions
class MenuItem(title0 : java.lang.String)
extends AbstractButton
listeners
reactions
     
     
     
Panel/Layout Example
class BorderPanel
extends Panel with LayoutContainer
contents = new BorderPanel {
  add(label, BorderPanel.Position.North)
  add(button, BorderPanel.Position.East)
  add(text, BorderPanel.Position.Center)
}
class BoxPanel(orientation : Value)
extends Panel with Wrapper
contents = new BoxPanel(Orientation.Vertical) {
  contents += label
  contents += button
  contents += text
}
class FlowPanel(alignment : Value)
extends Panel with Wrapper
contents = new FlowPanel(Orientation.Vertical) {
  contents += label
  contents += button
  contents += text
}
class GridBagPanel
extends Panel with LayoutContainer
class GridPanel(rows0 : Int, cols0 : Int)
extends Panel with Wrapper
contents = new GridPanel(2, 2) {
  contents += label
  contents += button
  contents += text
}

All Panels have: contents, listeners, reactions, contents, tooltip_=, listenTo, deafTo.
All LayoutContainers have add (comp : Component, c : Constraints) : Unit.