Version 1.8
Copyright © 2009 Lars Vogel
19.07.2011
| Revision History | ||
|---|---|---|
| Revision 0.1 | 14.02.2009 | Lars Vogel |
| Created | ||
| Revision 0.2 - 1.8 | 14.06.2009 - 19.07.2011 | Lars Vogel |
| bug fixes and enhancements | ||
Table of Contents
Scala stands for scalable language which indicates that Scala is suitable for small scripting tasks as well as large enterprise applications. The creator of Scala is Martin Odersky.
Scala is a general purpose programming language designed to express common programming patterns in a concise, elegant, and type-safe way. Scale compiles to Java bytecode and therefore runs on the JVM.
Scala is a hybrid language, it is a object-orientated programming language as well a functional programming language.
Scala has objects and classes. Objects are singletons and are defined via the keyword "object". Classes are defined via the keyword "class".
Scala does not support primitive types, everything is Scala is an object, e.g. the number 1 is an object and has methods.
Methods can use special signs, e.g. +, -, ->, =>. For example the sign "+" is a method defined for the Object integer. As Scala allows you to avoid the dot and the braces if a method has only one parameter you still can write 1+2 but this really means 1.+(2) and is a method call to the method "+" to the instance 1 of object integer.
Scala tries to be very concise, for example semicolons at the end of a line are optional. Scala follows the uniform access principle , which describes that the access to method invocation and field selection should be the same (this principle was taken from the programming language Eiffel).
You can use this update site http://www.scala-lang.org/scala-eclipse-plugin to install the Scala Plugin for Eclipse. See Eclipse Update Manager for using the update manager.
You need to activate the JDT Weaving. Select Windows -> Preferences -> JDT Weaving and press "Enable". A restart of Eclipse is required.

To create a Scala application you define an object (which is the equivalent of an Singleton in Java ).
Create a new Scale project "de.vogella.scala.first" via File -> New -> Project ->Scala Wizards -> Scala Projects


Press finish.
Right click on the "src" folder and select New - Package and create the package "de.vogella.scala.first".
Create the new scala object "Hello.scala".


Change the source code to the following.
package de.vogella.scala.first; object Hello { def main(args: Array[String]) { println("Hello, world!") } }
Right-click your application, Select Runs -As -> Scala application and enjoy the output in the console.

Scala has two types of variables.
The functional programming style of Scala emphasis the usage of val variables.
Scala is a strongly typed language, e.g. each variable has a specific type. The type declaration is optional; if no type is defined during declaration then the variable will get the type of the initial assigned value. This is called "type inference".
Create a scala project "de.vogella.scala.variables" and try the following code.
object VariablesTest extends Application { val firstName = "Lars" val lastName = "Vogel" var test = "changable" println(firstName) }
The examples are stored in project "de.vogella.scala.classexample".
A class in Scala is per default defined as public. Everything which is included in the body of the class and which is field or method definition defines the primary constructor of this class.
Here is a very simple class
package de.vogella.scala.classexample class Robot { val material = "steel"; }
The parameter of the primary constructor are directly defined in the class definition. Parameters are directly available within the class. To make them available outside of the class, either define a field and assign the parameter to it, or just add var or val in front of the variable in the primary constructor.
Here is an example for a class with parameters, one of them is automatically available via an accessor.
package de.vogella.scala.classexample class Robot { val material = "steel"; }
package de.vogella.scala.classexample object Test extends Application { val robot = new RobotWithConstructor (true, "steel") robot.printStatus // material can be accessed as it is defined via val in the primary constructor println (robot.material) // Status on cannot be reached, the following line would result in syntax error // robot.on }
Auxiliary constructors are defined via the keyword this. They have to call the primary construtor.
package de.vogella.scala.classexample class RobotWithAuxiliaryConstructor (on: Boolean, val material:String ) { def printStatus() = { println(on) println(material) } def this() = this(true, "Steel"); }
package de.vogella.scala.classexample class TestAuxiliary { val robot = new RobotWithAuxiliaryConstructor() robot.printStatus // material can be accessed as it is defined via val in the primary constructor println (robot.material) // Status on cannot be reached, the following line would result in syntax error // robot.on }
A class can inherit from another class via the keyword "extends".
package de.vogella.scala.classexample; class BetterRobot (material:String) extends RobotWithConstructor (true, material ) { }
Scala provides a very powerful extention of inheritance, traits. Traits will be covered later.
Objects are Singletons. There are for example used to represent an application.
package de.vogella.scala.classexample object Application { def main (args: Array[String]) { println("The application is running") } }
Functions in Scala are similar to methods in Java. They are defined with the keyword "def" and have an optional parameter list and a return parameter after the ":" sign. The body of the functional is indicated by "=" and then curly braces {}
The return parameter is for a non-recursive function optional and will be determined by Scala automatically based on the function expressions. Also the curly braces for the method body are optional if the function statement has only one statement.
If a function has no parameters you can leave the () away for the call. Also the dot is not required for calling a function with only one parameter.
Create a scala project "de.vogella.scala.functions" and try the following code.
package de.vogella.scala.functions object Function { def main(args: Array[String]) { println("Hello, world!") val f = Function; println(f.min(3,5)) println(f.min2(3,5)) // If you have no parameters you can leave the () away f.sayHello f.sayHello("Lars") // You can leave away the point and if you only have one paramter also the brackets f sayHello "Lars" } //Explicit return parameter def min(i:Int, j:Int):Int = { if (i>j) return i else return j } //Without explicit return parameter def min2(i:Int, j:Int) = { if (i>j) i else j } // One one line a body and no parameters def sayHello = println("Hello") // One parameter def sayHello(s: String ) = println("Hello " + s) }
For recursive functions you have to define the return type explicitly.
package de.vogella.scala.functions object Factorial { def main(args: Array[String]) { val f = Factorial println( f.factorial(5) ) println( f.factorial(6) ) println( f.factorial(7) ) println( f.factorial(8) ) } def factorial (x:BigInt):BigInt= { if (x==0) 1 else x* factorial (x-1) } }
Scala permits almost very sign to define a method. For example you can define a method with the name +.
As you can leave out the dot and the braces for methods with only one parameter you can write in Scala a + b and "+" is a call to your method on a with the parameter b.
override is a keyword in Scala. Everytime you override a function you have to indicate this via this keyword.
package de.vogella.scala.functions class OverrideExample { // Without override this would give an error override def toString() = "test" }
Scala supports the uniform access principle which states that it should not make a difference if the programmer access a variable directly or via a method.
The following demonstrates this. Create the Scala project "de.vogella.scala.uniformaccess".
From the client the usage of both versions of Square is the same.
package de.vogella.scala.uniformaccess class Square { private var l = 1 ; var wide = 1; def length = l; def length_=(s : Int)= { require (s > 0 ) this.l = s } }
package de.vogella.scala.uniformaccess class Square { var length = 1 ; var wide = 1; }
package de.vogella.scala.uniformaccess object Main { def main(args: Array[String]) { var s = new Square(); println(s.length); s.length = 2; println(s.length); } }
Scala provides the for loop which iterates over a collection. The function foreach on a collection allows to use a closure (function) on each element.
Objects have also helper functions, for example Integer provides to to() method which allows to count from a starting number object to the defined number.
Create a scala project "de.vogella.scala.loops" and try the following code.
package de.vogella.scala.loops object Loops { def main(args: Array[String]) { val list = List("Java", "Scala" , "Groovy" , "NET"); // Use foreach and print out every element list.foreach(n=> println(n)) // Use standard for for (n<-list){ println(n) } // Use method to println for (i<- 1.to(9)){ print (i) } // Use the shorter form println for (i<- 1 to 9){ print (i) } } }
Scala provides collections, like List, Array and Map.
A List in Scala is immutatable, e.g. it is not possible to add and remove entries from a list. If you add or remove an element from a list you always create a modified copy of the original list.
package de.vogella.scala.collections; object Lists { def main(args: Array[String]) { val languages = List("Java", ".NET", "C++") println (languages) println (languages(2)) println (languages.contains("Java")) // + should be replaced with ::: but the Eclipse does currenlty not support this val additionalLanguages = languages + ("COBOL") println (additionalLanguages) } }
Scala also supports Arrays. In an array you can change elements. It is not possible to add elements to an Array. This operation always created a modified copy of the existing array.
package de.vogella.scala.collections object ArrayTest { def main(args: Array[String]) { val languages = Array("Java", ".NET") println (languages) } }
The following shows how to create Maps.
package de.vogella.scala.collections object MapTest { def main(args: Array[String]) { val languages = Map("Scala"-> "JVM", "Java" -> "JVM", ".NET"-> "CLR"); println (languages("Scala")) } }
The following demonstrates several methods for collections. The count, filter and exists method allow to define a closure which identifies the correct element(s).
package de.vogella.scala.collections object CollectionsMethods { def main(args: Array[String]) { val list= List(1, 2, 3, 4) // Prints number of all elements println (list.size ) // Count only the elements which can be divided by 2 println (list.count(i=> i %2==0)) // Check if a elements in included in list println(list.exists(i=> i ==4)); println(list.exists(i=> i ==5)); // Using filter to get elements val newList = list.filter(i=> i>=3) println (newList) // Map does allow to transform a list val newList2 = list.map(i=> i*3) println (newList2) } }
Scala provides case clases which have certain special properties compared with standard classes. Case classes support
Pattern matching
a factory method to created new instances of these classes without using the new keyword
the constructor arguments can be accessed using automatically generated accessor functions
The toString, equals and hashCode methods are automatically created using the constructor arguments
For example the following defines a object Person including accessors for firstName and lastName.
package de.vogella.scala.caseclasses case class Person (firstName: String, lastName:String)
This object uses the Person class.
package de.vogella.scala.caseclasses object Main extends Application { val p = Person("Lars", "Vogel") println(p.toString()) println (p.firstName) println (p.lastName) }
Traits are similar to abstract classes you can also use them to define methods and variables. The difference is that every class in Scala can only extends one class (abstract or normal) but and can can extend / implement as many traits as it wants. By this Scala allows "multiple inheritance".
Scala multiple inheritance is safe, e.g. it doesn't have the so-called diomond problem. Scala solve this problem by a linearisation of the call path for the methods. So even if two traits implement the same method it is clean which one is called if a class implements both.
To use the trait the class extends the first trait and the other are used with the keyword "with". If the class already extends another class you use directly the keyword with.
Create a Scala project "de.vogella.scala.traits".
Create the following coding.
package de.vogella.scala.traits trait MyTrait { def sayHello() = println("Hello from MyTrait") }
package de.vogella.scala.traits trait MyTrait2 { def sayHello() = println("Hello from MyTrait2") def sayHello2() = println("Hello2 from MyTrait2") }
package de.vogella.scala.traits object TraitTest extends MyTrait with MyTrait2 { def main(args: Array[String]) = { sayHello sayHello2 } }
Scala provides several pre-defined traits which can be used. For example the "Ordered" Trait defines the method compare as abstract which the client needs to implement. The "Ordered" Trait pre-define the compare operations which can then be used directly.
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.de Google Group. I have created a short list how to create good questions which might also help you.
http://www.scala-lang.org/ Scala Homepage
http://www.scala-lang.org/node/94 Scala IDE for Eclipse - Homepage
https://lampsvn.epfl.ch/trac/scala Scala and Eclipse IDE bug tracker
http://www.artima.com/scalazine Scala Zine from Bill Venners http://www.artima.com
http://wiki.eclipse.org/Scala_Bundle Create a Scala OSGI bundle
http://neilbartlett.name/blog/2007/04/06/an-osgi-bundle-built-in-scala/ OSGi bundle created in Scala
http://www.codecommit.com/blog/java/interop-between-java-and-scala Interoperability Between Java and Scala
http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:using_scala_to_create_eclipse_rcp_applications Using Scala to Create Eclipse RCP Applications
http://www.coconut-palm-software.com/the_new_visual_editor/doku.php?id=blog:simplifying_swt_with_scala Simplifying SWT Code with Scala