(assuming you don't already know Scala)
+This lecture will focus on syntax.
+
+ package edu.buffalo.myapp
+
+ import java.io.File
+ import scala.io._
+
+ object MyApp
+ {
+ val message: String = "Hello World"
+
+ def main(args: Array[String]): Unit = {
+ println(message)
+ var stream: Stream = Stream.fromFile(new File("Hello.txt"))
+ for(line <- stream.getLines){
+ println(line)
+ }
+ }
+ }
+
+
+ package edu.buffalo.myapp
+
+
+ Package definitions are exactly like Java.
+
+ import java.io.File
+
+ Import statements bring classes into the namespace, making them available for use.
+
+
+ import scala.io._
+
+ '_' acts like a wildcard in scala.
+ import java.io.{ File, FileInputStream }
+
+ Curly braces group class names together as a shorthand when you import multiple classes from the same package.
+
+ object MyApp {
+
+ Objects in scala are "singletons". They act like Java classes with only static methods. E.g., you could call MyApp.main(...)
+
+
+ class MyClass(name: String, age: Int) {
+
+ Classes are defined much like java, except constructor fields are given directly in the class definitions. e.g., you would instantiate this class as new MyClass("Bob", "102").
+
+ class MyClass(name: String, age: Int)
+ extends MyAncestorClass
+ with MyTrait
+ with MyOtherTrait {
+
+
+ Inheritence is defined with the extends keyword. Like Java, Scala only allows single inheritance, but you add define interfaces and mixins through the with keyword.
+
+
+ trait MyTrait {
+ ...
+ }
+
+
+ Traits are (almost) like what Java calls interfaces.
+ +Unlike Java, a trait can define methods with implementations.
+
+ sealed trait MyTrait {
+ ...
+ }
+
+
+ Sealed traits can only be extended/with-ed within the same file.
+
+ val message: String = "Hello World"
+
+
+ Variables are defined by the val or var keywords. val variables are immutable (like Java's final keyword).
+ +Anywhere a variable is declared, it may be followed by a colon and a type. If omitted, Scala will guess.
+ +Generally prefer to use val wherever you can.
+
+ args: Array[String]
+
+
+ Generic types use square brackets ([]). This is like Java's angle brackets (<>)
+
+ def main(args: Array[String]): Unit = {
+
+
+ Define functions with the def keyword.
+ +The Colon-Type syntax is used to define the return type. Unit is like Java's void.
+ +The last line of the function will be returned by default, but you can use return to return a value sooner.
+ +Don't forget the =
+
+ for(line <- stream.getLines){
+ ...
+ }
+
+ This is scala's iterator syntax (Like Java's for(line : stream.getLines)
+
+
+ stream.getLines.foreach { line =>
+ ...
+ }
+
+ This is another way to write the same thing.
+ class Foo(bar: String) {
+ def apply(baz: String): String =
+ { bar + " " + baz }
+ }
+
+
+ The special function apply is used to let a class instance (or object) pretend to be a function.
+
+
+ val myFoo = new Foo("Abe")
+ val result = myFoo("Lincoln")
+ println(result)
+
+ prints Abe Lincoln
+ Scala has a robust library of collection types. Collections are usually referenced by their role.
+ +Collections are immutable by default, and already in the namespace (no more import java.util.*).
+ +Mutable collections live in the collections.mutable package if needed.
+
+ val seq = Seq[Int](1, 2, 3, 4)
+ val iseq = IndexedSeq[Int]("Alice", "Bolesław", "Coreline")
+ val map = Map(
+ "Cookie" -> "Chocolate Chip",
+ "Cake" -> "Red Velvet",
+ "Confection" -> "Gulab Jamun"
+ )
+ val opt = if(yes) { Some("A thing") } else { None }
+
+ Scala uses round brackets to access collection elements (remember apply?).
+ +
+ println(seq(1))
+ println(iseq(2))
+ println(map("Cookie"))
+
+
+ prints 2, Coreline, and Chocolate Chip
+
+ val a = (1, "Cookie", "Alice")
+ val b = (2, "Cake", "Bolesław")
+ val all = Seq(a, b)
+
+
+ Scala also has a "Tuple" type (like Python).
+ +The type is also parenthesized. The elements above would have type (Int, String, String)
+ +Access elements of a tuple by a._1, a._2, and so forth.
+ For example all(1)._2 is "Cake"
+ all.filter { x => x._2.equals("Cookie") }
+ .map { x => x._3 }
+
+ Returns Seq("Alice")
+
+ all.fold(0) { (accum, v) => accum + v._1 }
+
+ Returns 3 (the sum of the first tuple field)
+
+ all.fold(0) { _ + _._1 }
+
+
+ Underscores can sometimes be used as shorthands for lambda functions when a variable is only used once.
+
+ foo match {
+ case "bar" => println("It was bar")
+ case "baz" => println("Baz be here")
+ case x => println("It was actually "+x+" the whole time!")
+ }
+
+
+ match is like a switch statement in C/C++, or an elif chain in Python...
+ +... but far more powerful.
+
+ val longFoo = foo match {
+ case x:String => x.toLong
+ case y:Int => y * 100l
+ case _ => println("giving up!")
+ }
+
+
+ You can match based on type.
+
+ val longFoo = foo match {
+ case (x, y) => x.toLong
+ case y:Int => y * 100l
+ case _ => println("giving up!")
+ }
+
+
+ You can match based on tuple nesting.
+
+ case class Foo(a: String, b: Int)
+ case class Bar(foo: Foo, baz: String)
+
+
+ Case classes give you a bunch of stuff for "free"
+ +
+ val myFoo = Foo("Abe", 1)
+
+
+ For example, you don't need to use "new" to construct one.
+
+ val name = bar match {
+ case Foo(name, id) => name
+ }
+
+ But the big perk is that you can use them in match blocks.
+
+ val name = bar match {
+ case Bar(Foo(name, id), baz) => name
+ }
+
+ ... even nested.
+ +Scala uses case classes to make implementing union types easy.
+
+ sealed trait MyFooOrBar
+ case class Foo(a: String, b: Int) extends MyFooOrBar
+ case class Bar(foo: Foo, baz: String) extends MyFooOrBar
+
+
+ Scala's compiler will warn you if you have a match block for a sealed trait that doesn't match every possible case.
+Scala relies on the Scala Build Tool for compilation. It's similar to Maven.
+
+name := "myproject"
+version := "0.1"
+organization := "edu.buffalo.cse.odin",
+
+ Many IDEs provide SBT integration. See the Scala Getting Started Page and Scala Metals Page for more details.
+