Getting Started with Scala

5-Jun-11

Hello World  

   

/** Everybody·s first program */ object HelloWorld { def main(args: Array[String]) { println("Hello, World!") } } Save on a file named HelloWorld.scala Compile with scalac HelloWorld.scala (or from your IDE) Run with scala HelloWorld (or from your IDE) Generate documentation with scaladoc HelloWorld.scala The above code creates a single object 


Everything in the object is like Java¶s static Scala doesn¶t have static 

Scala does have classes; we¶ll get to those later
2

Most of the same flags * (@author.Comments  // and /*. * and wiki markup is used in preference to * HTML markup. etc. and additional * sentences give more detail.) are used.. As in Javadoc. the first sentence * is a summary sentence.*/ comments are as in Java /** Scaladoc comments are similar to Javadoc * comments. the * formatting convention is slightly different. */ def doNothing = ()  . However..

Short. String ScalaObject  All Scala reference types. ()  Unit is returned by functions that ³don't return anything´ (e.g. Long. Float. Int. println) All Java reference types. it has a ³bottom´ as well as a ³top´ AnyVal   Any   Boolean.Types  The type hierarchy is a lattice. Char. for example. not a tree  That is. including Array and List  AnyRef (corresponds to Object in Java)    Null (bottom of all AnyRef objects)  Nothing (bottom of Any) 4 . Byte. Double  Scala has no primitives²these are objects Unit (has only a single value.

comparison.Declaring variables and values      The syntax is var name: type = value // declares a variable val name: type = value // declares a value Values are immutable: they can¶t be changed The : type can almost always be left off²the type is inferred from the value The = value must (almost) always be supplied This also works: var x: Double = 5 Rules for alphanumeric names are just like in Java   But there are other kinds of names     Scope rules are just like in Java Capitalization conventions are just like in Java Arithmetic. but is otherwise the same as in Java 5 . not 4. and logical operators are just like in Java Indentation is 2 spaces.

for example the while loop.³Statements´  Scala¶s ³statements´ should really be called ³expressions. x = 3 * (2 * y + is obviously incomplete Because Scala lets you leave out a lot of unnecessary punctuation. but that¶s not good Scala practice 6 . Move along.´  The value of a block. sometimes a line that you think is complete really isn¶t complete (or vice versa)  You can end statements with semicolons. is the last value computed in the block A statement is ended by the end of the line (not with a semicolon) unless it is obviously incomplete    For example. the value of a = 5 is 5     The value of many statements. is () () is a value of type Unit () is the only value of type Unit () basically means ³Nothing to see here. {«}.´ because almost every statement has a value  For example.

etc. It isn¶t--if omitted and the condition is false. *=. the value of the if statement is () 7  while (condition) { statements }   do { statements } while (condition)   if (condition) { statements }   if (condition) { statements } else { statements }  .Familiar statement types  These are the same as in Java (but have a value):  variable = expression // also +=.  The value of the statement is the value of the variable The value of the statement is () The value is () The value is the value of the last statement executed Older descriptions of Scala say that the else is required.

length) { println(myArray(x)) }   for (x <.myArray) { println(x) }   for (x <.The for comprehension  Scala¶s for is much more powerful than Java¶s for  Consequently.1 to 10) { println(i) }  Prints the numbers 1 through 10 Prints the numbers 1 through 9 Prints all the values in myArray Prints all the values in myArray  for (i <. it is used much more often than the other kinds of loops   We will just cover some simple cases here for (i <.myArray if x % 2 == 0) { println(x) }  Prints all the even numbers in myArray .0 until myArray.1 until 10) { println(i) }   for (x <.

along with an explicit type:  val ary = new Array[Int](5) val ary2 = Array(3. new is not allowed:   Arrays in Scala are just another kind of object. 1. 6) val list2 = List[Int]() // An empty list must have an explicit type . 1. than Arrays    val list1 = List(3. 4.Arrays  Arrays in Scala are parameterized types   Array[String] is an Array of Strings. new is required. and used more often. they have no special syntax Scala¶s Lists are more useful. where String is a type parameter In Java we would call this a ³generic type´  When no initial values are given. 1. 6)  When initial values are given. 4. 1.

remember?) value :: list returns a list with value appended to the front list1 ::: list2 appends (³concatenates´) the two lists list. 1. are immutable  Operations on an immutable List return a new List list. 3) res22: List[Any] = List(abc.Simple List operations  By default.head (or list head) returns the first element in the list list.tail (or list tail) returns a list with the first element removed list(i) returns the ith element (starting from 0) of the list list(i) = value is illegal (immutable. 3)  Basic operations:         An operation on a List may return a List of a different type   There are over 150 built-in operations on Lists--use the API! . Lists. 2.contains(value) (or list contains value) tests whether value is in list scala> "abc" :: List(1. like Strings. 2.

String.Tuples  Scala has tuples.lang. using _1.String.abc. like Lists.5) scala> val tt = (3.5) tt: (Int. are immutable Tuples are a great way to return more than one value from a method! .)   scala> val t = Tuple3(3. "abc". 5.5. java...abc.5) scala> t. java._1 res28: Int = 3 t _1 also works (the dot is optional)  Tuples are referenced starting from 1. "abc".     Tuples.5. _2. up to size 22 (why 22? I have no idea.5) t: (Int. Double) = (3. Double) = (3. 5.lang. .

} is more readable (and easier to type) than if (name.  If you get mysterious syntax errors.")) { . if (name startsWith "Dr. both on this line and on the previous line . try putting the punctuation back in.startsWith("Dr.An aside.abbreviations  Scala lets you omit a lot of ³unnecessary´ punctuation  For example..... you should experiment with leaving out punctuation anywhere you think it might be okay However.. }    Readability matters! Therefore..") { .

String = yellow scala> m contains "apple" res3: Boolean = true scala> m("cherry") java. (banana.Maps  scala> val m = Map("apple" -> "red".red).yellow))   Notice that a Map is really just a list of Tuples The -> is provided as a more readable syntax  scala> m("banana") res2: java.String] = Map((apple.lang.String.Map[java.immutable.lang.java.NoSuchElementException: key not found: cherry   .lang. "banana" -> "yellow") m: scala.collection.util.

so no braces are needed  def isEven(n: Int) = n % 2 == 0   def countTo(n: Int) { for (i <. a Boolean) The result is just a single expression. the result will be () You can state the result type explicitly In this example.Simple function definitions  def isEven(n: Int) = { val m = n % 2 m == 0 }  The result is the last value (in this case.1 to 10) { println(i) } }   It¶s good style to omit the = when the result is () If you omit the =. half(7) will return 3.5 (!) If you use a return statement. you must state the result type explicitly  def half(n: Int): Double = n / 2    def half(n: Int): Int = return n / 2  .

etc.) and can be assigned to variables.Functions are first-class objects    Functions are values (like integers. it¶s a literal function Example (assigning a literal function to the variable foo):  scala> val foo = (x: Int) => if (x % 2 == 0) x / 2 else 3 * x + 1 foo: (Int) => Int = <function1> scala> foo(7) res28: Int = 22   The basic syntax of a function literal is parameter_list => function_body In this example. passed to and returned from functions. and so on Wherever you see the => symbol.foreach(i => println(2 * i)) . foreach is a function that takes a function as a parameter:  myList.

. .Functions as parameters   To define a function. 3) res4: Int = 30603  Example:  .n: Int)Int scala> def collatz(n: Int) = if (n % 2 == 0) n / 2 else 3 * n + 1 collatz: (n: Int)Int scala> doTwice(collatz.. type2. you must specify the types of each of its parameters Therefore. n: Int) = f(f(n)) doTwice: (f: (Int) => Int.. typeN) => return_type type => return_type // if only one parameter scala> def doTwice(f: Int => Int. to have a function parameter. you must know how to write its type:   (type1. 7) res2: Int = 11 scala> doTwice(a => 101 * a.

Higher-order methods on Lists  map applies a one-parameter function to every element of a List. 5. 3. 15. 11) scala> ll map double res5: List[Int] = List(4. 3) scala> ll filter (_ < 5) // abbreviated function where one parameter is used once res11: List[Int] = List(2. 33) scala> ll map (n => n > 5) res8: List[Boolean] = List(false. true. 6. 7. 11) ll: List[Int] = List(2. 3) . 3. 10. returning a List of those elements that pass the test   scala> ll filter(n => n < 5) res10: List[Int] = List(2. 22) scala> ll map (n => 3 * n) res6: List[Int] = List(6. 5. true)  filter applies a one-parameter test to every element of a List. 7. 21. false. returning a new List      scala> def double(n: Int) = 2 * n double: (n: Int)Int scala> val ll = List(2. false. 14. 9.

More higher-order methods  def filterNot(p: (A) => Boolean): List[A]  Selects all elements of this list which do not satisfy a predicate  def count(p: (A) => Boolean): Int  Counts the number of elements in the list which satisfy a predicate  def forall(p: (A) => Boolean): Boolean  Tests whether a predicate holds for every element of this list  def exists(p: (A) => Boolean): Boolean  Tests whether a predicate holds for at least one of the elements of this list  def find(p: (A) => Boolean): Option[A]  Finds the first element of the list satisfying a predicate. if any  def sortWith(lt: (A. A) => Boolean): List[A]  Sorts this list according to a comparison function .

length) case _ => println("I don't know what I am! :( ") }  Pattern matching on types:  ..Pattern matching  Pattern matching on literal values:  today match { case "Saturday" => println("Party! Party! Party!") case "Sunday" => println("Pray...") case day => println(day + " is a workday. :( ") } something match { case x: Int => println("I'm the integer " + x) case x: String => println("I'm the String \"" + x + "\"") println("My length is " + x.

it shouldn¶t be used any other time Instead. use an Option type. b) => if (a > b) a else b } Some(biggest) } else { None } max(myList) match { case Some(x) => println("The largest number is " + x) case None => println("There are no numbers here!!!") } .length > 0) { val biggest = (list(0) /: list) { (a.The Option type   Scala has null because it interoperates with Java. with values Some(value) and None   def max(list: List[Int]) = { if (list.

. .. to say what that code has accomplished . } require is often used at the beginning of a method  assert is used to document something that you ³know´ to be true   takeCis700course assert(languagesIKnow contains "Scala") assert is often used at the end of a block of code.The require and assert methods  require and assert are methods that throw an exception when their argument is false require is used to document something that must be true in order for the code to work    def sqrt(x: Double) = { require(x >= 0).

Dealing with exceptions  Scala¶s exception creation and throwing is like Java:   class RottenEggException extends Exception throw new RottenEggException  Catching a thrown exception uses pattern matching:  try { makeAnOmlet } catch { case ex: RottenEggException => println("#$%&#@") case ex: Exception => println("What went wrong?") } .

Mac.io. and Linux have different ³end-of-line codes (\r\n is Windows). which work on any platform.toList println(lines) }  } Testing file I/O List(first.io. which work only on Windows Windows. in paths. /. not backslashes.fromFile(file)._ import scala.getLines().Source val file = new File("testio. \.txt") val writer = new PrintWriter(file) writer write "first\r\n" writer write "second" writer. second) .File I/O  object TestIO { def main(args: Array[String]) { println("Testing file I/O") import java. and this causes problems val lines = Source.close()    Use correct case for file names (only Windows ignores case) Use forward slashes.

it¶s easy to get to the source code--and in most cases. the source code is easier to read than you might think . Scala¶s API documentation isn¶t very complete The good news is. but they aren¶t much help learning the API Unfortunately. Luke    Books and tutorials are good for learning the syntax of Scala.Use the source.

The End 25 .