diff --git a/src/teaching/cse-562/2021sp/slide/2021-02-04-Scala.erb b/src/teaching/cse-562/2021sp/slide/2021-02-04-Scala.erb new file mode 100644 index 00000000..ff4e4467 --- /dev/null +++ b/src/teaching/cse-562/2021sp/slide/2021-02-04-Scala.erb @@ -0,0 +1,457 @@ +--- +template: templates/cse4562_2021_slides.erb +title: Scala Introduction +date: Feb 4, 2021 +--- + +
+
+

My assumptions

+ +

(assuming you don't already know Scala)

+ +

This lecture will focus on syntax.

+
+ +
+

Some Terms

+ +
+
Package
+
An organizational unit clustering related functionality
+
Object
+
A 'singleton' class. (Like Java's static)
+
Companion Object
+
A 'singleton' class implementing methods related to a class
+
Case Class
+
A class with bonus features (we'll discuss shortly).
+
+
+
+ +
+
+

Hello World

+ +

+  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.
This is like import scala.io.* in Java. +
+ +
+

+  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. + +
+ Objects can also use the extends and with keywords. +
+
+ +
+

+  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.
+ { line => ... } is a lambda function
+ with line as a parameter. +
+
+ +
+

+  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 +
+ +
+ +
+
+

Collections

+ +

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.

+
+ +
+ +
+ +
+ For example List[T] and Array[T] are both Seq[T], but only the latter is also an IndexedSeq[T]. +
+ +
+ You almost never create collections of a specific type. The following all create collections: +

+      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 +
+ +
+

Tuples

+ +

+  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"

+
+ +
+ Hint: x -> y is shorthand for (x, y). Use this with Map constructors. +
+ +
+ +
+ +
+

+  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) +
+ +
+

A Shorthand

+

+  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 Classes

+

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

+
+
+ +
+
+

SBT

+ +

Scala relies on the Scala Build Tool for compilation. It's similar to Maven.

+
+ +
+ +
+ +
+ One class should have an object with a method defined as: + def main(args: Array[String]). +
+ +
+

A simple build.sbt

+ +

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

+
+
diff --git a/src/teaching/cse-562/2021sp/slide/ubodin.css b/src/teaching/cse-562/2021sp/slide/ubodin.css index f55c65ba..70860477 100644 --- a/src/teaching/cse-562/2021sp/slide/ubodin.css +++ b/src/teaching/cse-562/2021sp/slide/ubodin.css @@ -46,6 +46,8 @@ * * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se + * + * with edits (C) 2017-2021 Oliver Kennedy. */ /********************************************* * GLOBAL STYLES @@ -157,6 +159,10 @@ body { bottom: -10px; text-align: right; } +.reveal tt { + font-family: courier; + font-weight: bold; +} /* Ensure certain elements are never larger than the slide itself */ .reveal img, .reveal video, .reveal iframe {