Scala - Overview
Official website: https://www.scala-lang.org/
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 importedscala> 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, ()
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 thecompanion-object
of aclass
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)