Scala - Overview

Updated: 2018-12-08

Why Scala

  • Static typing
  • Type inference
  • Prefer immutable objects
  • Functional Programming
  • Interoperability with Java

Effective Scala

http://twitter.github.io/effectivescala/

Install Vim Scala plugin:

$ mkdir -p ~/.vim/{ftdetect,indent,syntax} && for d in ftdetect indent syntax ; do curl -o ~/.vim/$d/scala.vim https://raw.githubusercontent.com/derekwyatt/vim-scala/master/$d/scala.vim; done

"pimp my library"

http://www.artima.com/weblogs/viewpost.jsp?thread=179766

scala vs java

http://appliedscala.com/blog/2016/scala-ecosystem/

IO

List files in folder:

import java.io.File
val list = new File("folder").listFiles.map(_.getName).toList

Read all the lines from a text file

val lines = scala.io.Source.fromFile("/path/to/data.txt").getLines.toList

Scala vs Python

Scala: typed

scala> var a = 1
a: Int = 1

scala> a = "asdf"
<console>:8: error: type mismatch;
 found   : String("asdf")
 required: Int
       a = "asdf"
           ^

Python: no type check

>>> a = 1
>>> a
1
>>> a = "asdf"
>>> a
'asdf'

Import

  • scala is always available

  • java is always available

  • scala.X already imported, e.g.

    scala> scala.util.Random
    res3: util.Random.type = scala.util.Random$@7eda2dbb
    
    scala> util.Random
    res0: util.Random.type = scala.util.Random$@7eda2dbb
  • java.lang.X already imported

    scala> System.nanoTime
    res12: Long = 411664161567335

To show everything under scala:

scala> scala.<TAB><TAB>

apply/unapply

scala> case class Name(first: String, last: String)
defined class Name

scala> val baz = Name.apply("foo", "bar")
baz: Name = Name(foo,bar)

scala> Name.unapply(baz)
res0: Option[(String, String)] = Some((foo,bar))

sqlContext

scala> sqlContext.tables.show
+---------+-----------+
|tableName|isTemporary|
+---------+-----------+
|  mytable|       true|
+---------+-----------+

Parallel Collection

Get Parallelism Level

scala> (0 to 100).par.tasksupport.parallelismLevel
res25: Int = 8

Case classes

  • are regular classes which
  • export their constructor parameters and which
  • provide a recursive decomposition mechanism via pattern matching.

Data

  • A literal (or literal data) is data that appears directly in the source code, like the number 5, the character A, and the text “Hello, World.”
  • A value is an immutable, typed storage unit. A value can be assigned data when it is defined, but can never be reassigned.
  • A variable is a mutable, typed storage unit. A variable can be assigned data when it is defined and can also be reassigned data at any time.

multiline literals

A multiline String can be created using triple-quotes.

eq vs equals

  • eq: compare ref
  • equals: compare value

e.g.

test("equals") {
  val a = Seq(1,2,3)
  val b = Seq(1,2,3)
  assert(a.equals(b))
  assert(!a.eq(b))

  val c = Seq(4,5,6)
  assert(!a.equals(c))
  assert(!a.eq(c))

  val d = a
  assert(d.eq(a))

  val s1 = "asdf"
  val s2 = "asdf"
  assert(s1.eq(s2))
}

Sum

scala> val a = Seq(1,2,3)
a: Seq[Int] = List(1, 2, 3)

scala> val b = Seq(4,5,6)
b: Seq[Int] = List(4, 5, 6)

scala> val c = a.zip(b)
c: Seq[(Int, Int)] = List((1,4), (2,5), (3,6))

scala> val d = c.map(t => t._1 * t._2)
d: Seq[Int] = List(4, 10, 18)

scala> d.sum
res2: Int = 32

&& || vs & |

The Boolean comparison operators && and || are lazy in that they will not bother evaluating the second argument if the first argument is sufficient. The operators & and | will always check both arguments before returning a result.

object vs class

think of the object keyword as creating a singleton object of a class that is defined implicitly

Start Scala REPL by

$ scala
Welcome to Scala version 2.XX.X (Java HotSpot(TM) 64-Bit Server VM, Java 1.X.X).
Type in expressions to have them evaluated.
Type :help for more information.

scala>

Value vs Variable

compare with

scala> val x = 1 to 5
x: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)

the response starts with the name of the value x:

Type Inference

scala> val x = List(1, true)
x: List[AnyVal] = List(1, true)

scala> val x = List((1, true), (2, "hello"))
x: List[(Int, Any)] = List((1,true), (2,hello))

Basic Types

scala> val x:Int = 5
x: Int = 5

scala> x
res1: Int = 5

scala> x * 2
res2: Int = 10

scala> res1 * res2
res3: Int = 50

scala> val x = 10L
x: Long = 10

scala> val x = 10
x: Int = 10

scala> val x = 10D
x: Double = 10.0

scala> val x = 10F
x: Float = 10.0

scala> val x = "a"
x: String = a

scala> val x = 'a'
x: Char = a


scala> val x = "\t"
x: String = " "

Multiline strings are literal, and so do not recognize the use of backslashes as the start of special characters

scala> val x = """\t"""
x: String = \t

scala> val greeting = """She suggested reformatting the file
      | by replacing tabs (\t) with newlines (\n);
      | "Why do that?", he asked. """

The Unit literal is an empty pair of parentheses, ()

Print

scala> val x = 5
x: Int = 5

scala> println("x=x")
x=x

scala> println("x=" + x)
x=5

scala> println(s"x=$x")
x=5

scala> println(s"x=$x*2")
x=5*2

scala> println(s"x=${x*2}")
x=10

  To use printf notation change the prefix to an “f”
scala> println(f"x=${x*2}%.2f")
x=10.00

scala> println(s"x=${x*2}%.2f")
x=10%.2f

Copy jars To Folder

add this to build.sbt

retrieveManaged := true

jars will be copied to <project_folder>/lib_managed

sbt Dependency %% vs %

  • %%: auto-append scala version
  • %: no scala version appended
libraryDependencies += "org.apache.spark" %% "spark-mllib" % "1.4.1"

is equivalent to

libraryDependencies += "org.apache.spark" % "spark-mllib_2.10" % "1.4.1"

Companion Object

  • An object is a singleton.
  • An object is said to be the companion-object of a class if they share the same name.
  • Think of the methods defined in the companion-object to be static: they are accessed by the name of the class.

Random

String interpolation

scala> val approx = 355/113f

approx: Float = 3.141593

scala> s"Fish n chips n vinegar, \${"pepper "\*3}salt"
res1: String = Fish n chips n vinegar, pepper pepper pepper salt
println(s"Pi, using 355/113, is about \$approx." )
scala> val red = "red" -> "0xff0000"
red: (String, String) = (red,0xff0000)

scala> val reversed = red.\_2 -> red.\_1
reversed: (String, String) = (0xff0000,red)