1 / 26

Getting Started with Scala

Getting Started with Scala. 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)

dyanne
Download Presentation

Getting Started with Scala

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Getting Started with Scala

  2. 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

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

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

  5. Declaring variables and values • The syntax isvar name: type = value// declares a variableval 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 = valuemust (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 almost the same as those in Java • Capitalization conventions are just like in Java • Arithmetic, comparison, and logical operators are just like in Java • Indentation is 2 spaces, not 4, but is otherwise the same as in Java

  6. “Statements” • Scala’s “statements” should really be called “expressions,” because almostevery statement has a value • For example, the value of a = 5 is 5 • The value of many statements, for example the while loop,is () • () is a value of type Unit • () is the only value of type Unit • () basically means “Nothing to see here. Move along.” • The value of a block, {…}, 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, or if the next line cannot begin a valid statement • For example, x = 3 * (2 * y + is obviously incomplete • Because Scala lets you leave out a lot of unnecessary punctuation, sometimes a line that you think is complete really isn’t complete (or vice versa) • You can end statements with semicolons, but that’s not good Scala practice

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

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

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

  10. Simple List operations • By default, Lists, like Strings, are immutable • Operations on an immutable List return a new List • Basic operations: • list.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, remember?) • value :: list returns a list with value appended to the front • list1 ::: list2 appends (“concatenates”) the two lists • list.contains(value) (or list contains value) tests whether value is in list • An operation on a List may return a List of a different type • scala>"abc" :: List(1, 2, 3)res22: List[Any] = List(abc, 1, 2, 3) • There are over 150 built-in operations on Lists--use the API!

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

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

  13. Maps • scala> val m = Map("apple" -> "red", "banana" -> "yellow")m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((apple,red), (banana,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.lang.String = yellow • scala> m contains "apple"res3: Boolean = true • scala> m("cherry")java.util.NoSuchElementException: key not found: cherry

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

  15. Functions are first-class objects • Functions are values (like integers, etc.) and can be assigned to variables, passed to and returned from functions, and so on • Wherever you see the => symbol, 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 + 1foo: (Int) => Int = <function1>scala> foo(7)res28: Int = 22 • The basic syntax of a function literal isparameter_list=>function_body • In this example, foreach is a function that takes a function as a parameter: • myList.foreach(i => println(2 * i))

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

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

  18. 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

  19. 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. :( ")} • Pattern matching on types: • 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.length) case _ => println("I don't know what I am! :( ") }

  20. The Option type • Scala has null because it interoperates with Java; it shouldn’t be used any other time • Instead, use an Option type, with values Some(value) and None • def max(list: List[Int]) = { if (list.length > 0) { val biggest = (list(0) /: list) { (a, 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!!!")}

  21. 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); ... } • require is often used at the beginning of a method • assert is used to document something that you “know” to be true • takeCis700courseassert(languagesIKnow contains "Scala") • assert is often used as “executable documentation”

  22. The ensuring method • The ensuring method applies a predicate to a value and, if the predicate result is true, returns the value, otherwise throws an AssertionError • Syntax: value ensuring(predicate) • scala> 12 ensuring(true)res1: Int = 12 • scala> 12 ensuring(_ > 10)res2: Int = 12 • scala> def twice(x: Int) = 2 * x ensuring(_ > 0)twice: (x: Int)Int • scala> twice(3)res3: Int = 6 • scala> twice(-5)java.lang.AssertionError: assertion failed (+ many lines) • ensuring can be useful to guarantee the result of a method

  23. 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?")}

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

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

  26. The End

More Related