Scala is a new programming language which first had put its head up to the world in 2001 though, as we all know, programming languages need a lot of time to become what one calls “mature”. That’s why I call it a young programming language and it still changes.
Scala is built on top of java. It generates Java bytecode and it can be run on any platform java runs on. Scala combines functional and object oriented programming styles, it’s very scalable and it’s mature. There is a Scala plugin for the current stable netbeans (wiki.netbeans.org/Scala), you can rely on the tested web framework Lift for web application development, you can do rich gui application development and just anything you’ll probably need for your next project.
I love perl e.g. for everything I do. From scripting migration scripts, parsing all kinds of text files, to serious web application development but when it comes to gui development perl really sucks. This is where Scala can fit in my possible gap. (ps.: I know that perl is able to do gui development but it’s simply utterly fat and everything but elegant to ship and code for it).
Scala programming wise is seen as a general purpose language which smoothly interoperates with java itself. Scala is a type-safe language but even though you are teached to use immutable objects and methods all the time it’s possible to have mutable objects as well.
Scala can also be a script interpreter, so you can write “simple” scripts but for me this is
And to give you some buzzwords for scala, here they are:
- actors and concurrency
- stateful objects
- traits
- closures
- assertions
- unit tests
- getting tired of buzzwords dot com :/
To learn Scala you can buy the brilliant book “Programming in Scala” by Martin Odersky, Lex Spoon and Bill Venners or you can read the good online resources which can get you started quickly as well but I really recommend this book because it’s for people who already know some other programming language and who are familiar with programming in general. I really hate books who start to explain some bloated IDE just to start to explain every menu item step-by-step.
Tiny examples for the “scala” interpreter
_Hello World_
println("Hello "+args(0)+"!")
_Args_
var i = 0
while(i < args.length) {
println(args(i))
i += 1
}
_Args2_
args.foreach(arg => println(arg))
_Arrays_
val numNames = Array("zero", "one", "two")
println(numNames(1))
_Lists_
val oneTwoThree = List(1,2,3)
println(oneTwoThree(2))
println()
val oneTwo = List(1,2)
val threeFour = List(3,4)
val oneTwoThreeFour = oneTwo ::: threeFour
println(""+oneTwo+" and "+threeFour+" were not mutated.")
println("Thus, "+oneTwoThreeFour+" is a new list.")
println()
val foo = List(2,3)
val bar = 1 :: foo
println(bar)
println()
val blub = 1 :: 2 :: 3 :: Nil
println(blub)
println()
val list1 = List()
println(list1)
val list2 = Nil
println(list2)
val list3 = List("Cool", "tools", "rule");
println(list3)
val list4 = "Will" :: "fill" :: "until" :: Nil
println(list4)
val list5 = List("a","b") ::: List("c","d")
println(list5)
println(list5(1))
val entrycount = list5.count(s => s.length == 1)
println(entrycount)
println()
val cars = "Audi" :: "BMW" :: "Mercedes" :: "Ford" :: Nil
println(cars)
val good_cars = cars.filter(s => s == "Audi")
println(good_cars)
println()
val sporty_cars = cars.dropRight(2)
println(sporty_cars)
println()
val cars_with_b_letter = cars.filter(s => s.startsWith("B"))
println(cars_with_b_letter)
println()
cars.foreach(s => println(s))
println()
println(cars.head)
println(cars.init)
if (cars.isEmpty) println("empty") else println("not empty: "+cars)
println()
println(cars.last)
println(cars.length)
println(cars.map(s => s + " cars"))
println()
val clean_list = cars.remove(s => s.length == 4)
println(clean_list)
println(clean_list.mkString(" "))
println()
val reverse_cars = cars.reverse
println(reverse_cars)
println()
val sorted_cars = cars.sort((s, t) => s.charAt(0).toLowerCase < t.charAt(0).toLowerCase)
println(sorted_cars)
println()
_Maps_
val romanNumeral = Map(1 -> "I", 2 -> "II", 3 -> "III", 4 -> "IV") println(romanNumeral(4))
_Tuples_
val pair = ("Audi", 80)
println(pair._1)
println(pair._2)
println()
_Sets_
var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear"
println(jetSet.contains("cessna"))
println(jetSet)
_Classes_
class FooBar {
var bar = 10
}
val foo1 = new FooBar
foo1.bar = 11
class FooBar {
private var bar = 10
def getBar(): Int = {
return bar
}
}
val foo1 = new FooBar
foo1.getBar
class FooBar {
private var bar = 10
def getBar(): Int = bar
}
val foo1 = new FooBar
foo1.getBar
_A Scala app_
object Scalapp {
def main(args: Array[String]) {
println("hello world");
}
}
scalac Scalapp.scala scala Scalapp
object Scalapp extends Application {
println("hello world");
}
Datatypes
Byte-27 to 27 - 1 (inclusive) Short-215 to 215 - 1 (inclusive) Int-231 to 231 - 1 (inclusive) Long-263 to 263 - 1 (inclusive) Char0 to 216 - 1 (inclusive) String Float32 bit single precision float Double64 bit double precision float Booleantrue | false
println("""|Here, I am writing more than one line
|please get me out of here""".stripMargin)
def setNewName(theName: Symbol, value: Any) {
// update code
}
scala> val s = 'aSymbol s: Symbol = 'aSymbol scala> s.name res0: String = aSymbol scala>
_Operator Notation_
val firstName = "Andreas" firstName indexOf 's'
will be firstName.indexOf(’s’)
class Brand(brand: String, model: String) {
require(!brand.isEmpty)
require(!mode.isEmpty)
override def toString = brand+' '+model
private def makeBrandCode(brand: String, model: String): String = {
brand.toLowerCase+'_'+model.toLowerCase
}
}
val foobar = new Brand("Audi","80")
conditionals
object Test {
def main (args: Array[String]) {
val filename = if (!args.isEmpty) args(0) else "default.txt"
}
}
while
object Test {
def main (args: Array[String]) {
var run = 0;
while (run < 10) {
println("run: "+run)
run = run + 1
}
}
}
for
object Test {
def main (args: Array[String]) {
val filesHere = (new java.io.File(".")).listFiles
for (file <- filesHere)
println(file)
for (i <- 1 to 4)
println("Iteration "+i)
for (i <- 1 until 4)
println("Iteration "+i)
val moreFiles = (new java.io.File(".")).listFiles
for (file <- moreFiles if file.getName.endsWith(".scala"))
println(file)
}
}
Exceptions
package scalaapplication1
object Main {
/**
* @param args the command line arguments
*/
def main(args: Array[String]): Unit = {
val i = 13
val result = if (i % 2 == 0) i / 2 else throw new RuntimeException("i must be even")
}
}
package scalaapplication1
object Main {
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
def main(args: Array[String]): Unit = {
try {
val my_file = new FileReader("config.json")
my_file.close
} catch {
case ex: FileNotFoundException => this.handle_file_not_found
case ex: IOException => this.handle_io_exception
}
}
def handle_file_not_found(): Unit = {
// handle the file not found exception here
println("hey, file not found!")
}
def handle_io_exception(): Unit = {
// handle the io exception here
println("io exception")
}
}
Switch/Match
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val test = "Andreas"
test match {
case "Bla" => println("Bla")
case "Andreas" => println("Andreas")
case _ => println("none")
}
}
}
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val test = "Andreas"
val first_name = test match {
case "Bla" => "Bla"
case "Andreas" => "Andreas"
case _ => "none"
}
println(first_name)
}
}
Local functions
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
foobar("Round",10)
def foobar(value: String, times: Int) {
for (run <- 1 to times) {
println(value+" "+run)
}
}
}
}
First class functions
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
var html_title = (value: String) => ""+value+"
"
println(html_title("Andreas Schipplock"))
println(html_title("Introduction"))
}
}
First class functions placeholders
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val foo = (_: Int) + (_: Int)
println(foo(1,9))
}
}
Partially applied functions
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val my_numbers = List(0,1,2,3,4,5,6,7,8,9)
my_numbers.foreach(println _)
}
}
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
def sum(a: Int, b: Int, c: Int) = a + b + c
val foo = sum(5, _: Int, 10)
println(foo(5))
}
}
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
def sum(a: Int, b: Int, c: Int) = a + b + c
val bar = sum _
println(bar(1,2,3))
}
}
Repeated parameters
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
echo("Ich", "bin", "ein", "Auto")
}
def echo(args: String*): Unit = {
for (arg <- args) println(arg)
}
}
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val foobar = Array("ich","bin","ein","auto")
echo(foobar: _*)
}
def echo(args: String*): Unit = {
for (arg <- args) println(arg)
}
}
Control abstraction
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val foobar = FileMatcher
for (bar <- foobar.filesContaining("args")) {
println(bar)
}
}
}
object FileMatcher {
private def filesHere = (new java.io.File("/tmp")).listFiles
private def filesMatching(matcher: String => Boolean) = {
for (file <- filesHere; if matcher(file.getName))
yield file
}
def filesEnding(query: String) = filesMatching(_.endsWith(query))
def filesContaining(query: String) = filesMatching(_.contains(query))
def filesRegex(query: String) = filesMatching(_.matches(query))
}
Simple classes
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val test = new ArrayElement(Array("Hello","World"))
println(test.width)
}
}
abstract class Element {
def contents: Array[String]
def height: Int = contents.length
def width: Int = if (height == 0) 0 else contents(0).length
}
class ArrayElement(conts: Array[String]) extends Element {
def contents: Array[String] = conts
}
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val test = new ArrayElement(Array("Hello","World"))
println(test.width)
}
}
abstract class Element {
def contents: Array[String]
def height: Int = contents.length
def width: Int = if (height == 0) 0 else contents(0).length
}
class ArrayElement(val contents: Array[String]) extends Element
Invoking a superclass constructor
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val test = new ArrayElement(Array("Hello","World"))
println(test.width)
val test2 = new LineElement("Test")
println(test2.width)
}
}
abstract class Element {
def contents: Array[String]
def height: Int = contents.length
def width: Int = if (height == 0) 0 else contents(0).length
}
class ArrayElement(val contents: Array[String]) extends Element
class LineElement(s: String) extends ArrayElement(Array(s)) {
override def width = s.length
override def height = 1
}
Traits
package scalaapplication1
object Main {
def main(args: Array[String]): Unit = {
val test = new FooElement("bla")
println(test.contents)
test.foo
}
}
trait FooBar {
def foo() {
println("Bla")
}
}
abstract class Element {
def contents: String
}
class FooElement(s: String) extends Element with FooBar {
override def contents: String = s
}
