// Scala Lecture 1+ −
//=================+ −
+ −
+ −
+ −
// Value assignments+ −
// (their names should be lower case)+ −
//====================================+ −
+ −
+ −
val x = 42+ −
val y = 3 + 4 + −
val z = x / y+ −
val x = 70+ −
print(z)+ −
+ −
+ −
// (you cannot reassign values: z = 9 will give an error)+ −
//var z = 9+ −
//z = 10+ −
+ −
// Hello World+ −
//=============+ −
+ −
// an example of a stand-alone Scala file+ −
// (in the assignments you must submit a plain Scala script)+ −
+ −
object Hello extends App { + −
println("hello world")+ −
}+ −
+ −
// can then be called with+ −
//+ −
// $> scalac hello-world.scala+ −
// $> scala Hello+ −
//+ −
// $> java -cp /usr/local/src/scala/lib/scala-library.jar:. Hello+ −
+ −
+ −
+ −
// Collections+ −
//=============+ −
+ −
List(1,2,3,1)+ −
Set(1,2,3,1)+ −
+ −
// picking an element in a list+ −
val lst = List(1, 2, 3, 1)+ −
+ −
lst(0)+ −
lst(2)+ −
+ −
// head and tail+ −
lst.head+ −
lst.tail+ −
+ −
// some alterative syntax for lists+ −
+ −
Nil // empty list+ −
+ −
1 :: 2 :: 3 :: Nil+ −
List(1, 2, 3) ::: List(4, 5, 6)+ −
+ −
// also+ −
List(1, 2, 3) ++ List(3, 6, 5)+ −
Set(1, 2, 3) ++ Set(3, 6, 5)+ −
+ −
// ranges+ −
1 to 10+ −
(1 to 10).toList+ −
(1 to 10).toList.toString+ −
+ −
(1 until 10).toList+ −
+ −
+ −
// Equality in Scala is structural+ −
//=================================+ −
val a = "Dave2"+ −
val b = "Dave"+ −
+ −
if (a == b) println("Equal") else println("Unequal")+ −
+ −
Set(1,2,3) == Set(3,1,2)+ −
List(1,2,3) == List(3,1,2)+ −
+ −
+ −
// this applies to "concrete" values...pretty much + −
// everything; but for example you cannot compare + −
// functions (later), and also not arrays+ −
+ −
Array(1) == Array(1)+ −
+ −
+ −
// Printing/Strings+ −
//==================+ −
+ −
println("test")+ −
+ −
val tst = "This is a " ++ "test" + −
+ −
print(tst) + −
println(tst) + −
+ −
val lst = List(1,2,3,1)+ −
+ −
println(lst.toString)+ −
+ −
println(lst.mkString)+ −
println(lst.mkString(","))+ −
+ −
// some methods take more than one argument+ −
+ −
println(lst.mkString("{", ",", "}"))+ −
+ −
// (in this case .mkString can take no, one, + −
// or three arguments...this has to do with+ −
// default arguments)+ −
+ −
+ −
// Conversion methods+ −
//====================+ −
+ −
List(1,2,3,1).toString+ −
List(1,2,3,1).toSet+ −
+ −
"hello".toList+ −
"hello".toSet+ −
+ −
+ −
1.toDouble+ −
+ −
1 // an Int+ −
1L // a Long+ −
1F // a Float+ −
1D // a Double+ −
+ −
// useful list methods on lists+ −
//==============================+ −
+ −
List(1,2,3,4).length+ −
List(1,2,3,4).reverse+ −
List(1,2,3,4).max+ −
List(1,2,3,4).min+ −
List(1,2,3,4).sum+ −
List(1,2,3,4).take(2).sum+ −
List(1,2,3,4).drop(2).sum+ −
List(1,2,3,4,3).indexOf(3)+ −
+ −
"1,2,3,4,5".split(",").mkString("\n")+ −
"1,2,3,4,5".split(",").toList+ −
"1,2,3,4,5".split(",3,").mkString("\n")+ −
+ −
"abcdefg".startsWith("abc")+ −
+ −
+ −
// Types (see slide)+ −
//===================+ −
+ −
/* Scala is a strongly typed language+ −
+ −
* base types+ −
+ −
Int, Long, BigInt, Float, Double+ −
String, Char+ −
Boolean...+ −
+ −
* compound types + −
+ −
List[Int]+ −
Set[Double]+ −
Pairs: (Int, String) + −
List[(BigInt, String)]+ −
Option[Int]+ −
+ −
* user-defined types (later)+ −
+ −
*/+ −
+ −
+ −
// you can make the type of a value explicit+ −
val name = "bob"+ −
+ −
+ −
// type errors+ −
math.sqrt("64".toDouble)+ −
+ −
// produces+ −
//+ −
// error: type mismatch;+ −
// found : String("64")+ −
// required: Double+ −
// math.sqrt("64")+ −
+ −
+ −
// Pairs/Tuples+ −
//==============+ −
+ −
val p = (1, "one")+ −
p._1+ −
p._2+ −
+ −
val t = (4,1,2,3)+ −
t._4+ −
+ −
+ −
List(("one", 1), ("two", 2), ("three", 3))+ −
+ −
+ −
// Function Definitions+ −
//======================+ −
+ −
+ −
def incr(x: Int) : Int = x + 1+ −
def double(x: Int) : Int = x + x+ −
def square(x: Int) : Int = x * x+ −
+ −
def str(x: Int) : String = x.toString+ −
+ −
+ −
incr(3)+ −
double(4)+ −
square(6)+ −
str(3)+ −
+ −
+ −
// The general scheme for a function: you have to give a + −
// type to each argument and a return type of the function+ −
//+ −
// def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = {+ −
// + −
// }+ −
+ −
+ −
+ −
// If-Conditionals+ −
//=================+ −
+ −
// - Scala does not have a then-keyword+ −
// - !!both if-else branches need to be present!!+ −
+ −
def fact(n: Int) : Int = + −
if (n == 0) 1 else n * fact(n - 1)+ −
+ −
fact(5)+ −
fact(150)+ −
+ −
/* boolean operators+ −
+ −
== equals+ −
!= not equals+ −
! not+ −
&& || and, or+ −
*/+ −
+ −
+ −
+ −
def fib(n: Int) : Int = {+ −
if (n == 0) 1 else+ −
if (n == 1) 1 else fib(n - 1) + fib(n - 2)+ −
}+ −
+ −
fib(9)+ −
+ −
+ −
+ −
+ −
//gcd - Euclid's algorithm+ −
+ −
def gcd(a: Int, b: Int) : Int = {+ −
if (b == 0) a + −
else gcd(b, a % b)+ −
}+ −
+ −
gcd(48, 18)+ −
+ −
+ −
def power(x: Int, n: Int) : Int =+ −
if (n == 0) 1 else x * power(x, n - 1) + −
+ −
power(5, 5)+ −
+ −
// BTW: no returns!!+ −
// "last" line (expression) in a function determines the + −
// result+ −
+ −
def average(xs: List[Int]) : Int = {+ −
if (xs.length == 0) 0 + −
else xs.sum / xs.length+ −
}+ −
+ −
average(List())+ −
+ −
+ −
+ −
// For-Comprehensions (not For-Loops)+ −
//====================================+ −
+ −
val lst = (1 to 10).toList+ −
for (n <- lst) yield n * n + −
+ −
+ −
for (n <- lst) yield { + −
square(n) + double(n)+ −
}+ −
+ −
for (n <- (1 to 10).toList; + −
m <- (1 to 5).toList) yield (n, m, n * m)+ −
+ −
+ −
// you can assign the result of a for-comprehension+ −
// to a value+ −
val mult_table = + −
for (n <- (1 to 10).toList; + −
m <- (1 to 10).toList) yield n * m+ −
+ −
println(mult_table.mkString)+ −
mult_table.sliding(10,10).mkString("\n")+ −
+ −
// for-comprehensions also work for other+ −
// collections+ −
+ −
for (n <- Set(10,12,4,5,7,8,10)) yield n * n+ −
+ −
for (n <- (1 to 10)) yield {+ −
n * n + −
}+ −
+ −
// with if-predicates / filters+ −
+ −
if (1 == 2) "a" else "b"+ −
+ −
for (n <- (1 to 3).toList; + −
m <- (1 to 3).toList;+ −
if (n + m) % 2 == 0) yield (n, m)+ −
+ −
+ −
// with patterns+ −
+ −
val lst = List((1, 4), (2, 3), (3, 2), (4, 1))+ −
+ −
for ((m, n) <- lst) yield m + n + −
+ −
for (p <- lst) yield p._1 + p._2 + −
+ −
+ −
// general pattern of for-yield + −
// (yield can be several lines)+ −
+ −
for (pat <- ...) yield {+ −
// potentially complicated+ −
// calculation of a result+ −
}+ −
+ −
// For without yield+ −
//===================+ −
+ −
// with only a side-effect (no list is produced),+ −
// has no "yield"+ −
+ −
for (n <- (1 to 10).toList) println(n * n)+ −
+ −
for (n <- (1 to 10).toList) yield n * n+ −
+ −
// BTW: a roundabout way of printing out a list, say+ −
val lst = ('a' to 'm').toList+ −
+ −
for (i <- (0 until lst.length)) println(lst(i))+ −
+ −
// Why not just? Why making your life so complicated?+ −
for (c <- lst) println(c)+ −
+ −
+ −
+ −
// Functions producing multiple outputs+ −
//======================================+ −
+ −
def get_ascii(c: Char) : (Char, Int) = + −
(c, c.toInt)+ −
+ −
get_ascii('a')+ −
+ −
+ −
// .maxBy, sortBy with pairs+ −
def get_length(s: String) : (String, Int) = + −
(s, s.length) + −
+ −
val lst = List("zero", "one", "two", "three", "four", "ten")+ −
val strs = for (s <- lst) yield get_length(s)+ −
+ −
strs.sortBy(_._2)+ −
strs.sortBy(_._1)+ −
+ −
strs.maxBy(_._2)+ −
strs.maxBy(_._1)+ −
+ −
+ −
+ −
+ −
+ −
// Aside: concurrency + −
// scala -Yrepl-class-based -cp scala-parallel-collections_2.13-0.2.0.jar + −
+ −
for (n <- (1 to 10)) println(n)+ −
+ −
import scala.collection.parallel.CollectionConverters._+ −
+ −
for (n <- (1 to 10).par) println(n)+ −
+ −
+ −
// for measuring time+ −
def time_needed[T](n: Int, code: => T) = {+ −
val start = System.nanoTime()+ −
for (i <- (0 to n)) code+ −
val end = System.nanoTime()+ −
(end - start) / 1.0e9+ −
}+ −
+ −
val list = (1 to 1000000).toList+ −
time_needed(10, for (n <- list) yield n + 42)+ −
time_needed(10, for (n <- list.par) yield n + 42)+ −
+ −
// ...but par does not make everything faster+ −
+ −
list.sum+ −
list.par.sum+ −
+ −
time_needed(10, list.sum)+ −
time_needed(10, list.par.sum)+ −
+ −
+ −
// Mutable vs Immutable+ −
//======================+ −
//+ −
// Remember:+ −
// - no vars, no ++i, no +=+ −
// - no mutable data-structures (no Arrays, no ListBuffers)+ −
+ −
// But what the heck....lets try to count to 1 Mio in parallel+ −
+ −
var cnt = 0+ −
+ −
for(i <- (1 to 1000000).par) cnt += 1+ −
+ −
println(s"Should be 1 Mio: $cnt")+ −
+ −
+ −
+ −
// Or+ −
// Q: Count how many elements are in the intersections of + −
// two sets?+ −
// A; IMPROPER WAY (mutable counter)+ −
+ −
def count_intersection(A: Set[Int], B: Set[Int]) : Int = {+ −
var count = 0+ −
for (x <- A.par; if (B contains x)) count += 1 + −
count+ −
}+ −
+ −
val A = (0 to 999).toSet+ −
val B = (0 to 999 by 4).toSet+ −
+ −
count_intersection(A, B)+ −
+ −
// but do not try to add .par to the for-loop above+ −
+ −
+ −
//propper parallel version+ −
def count_intersection2(A: Set[Int], B: Set[Int]) : Int = + −
A.par.count(x => B contains x)+ −
+ −
count_intersection2(A, B)+ −
+ −
+ −
//another bad example+ −
def test() = {+ −
var cnt = 0+ −
for(i <- (1 to 1000000).par) cnt += 1+ −
println(cnt)+ −
}+ −
+ −
test()+ −
+ −
+ −
+ −
// Regular Expressions (the built in ones)+ −
+ −
val s = """Any so-called "politician" should respect a vote."""+ −
print(s)+ −
+ −
print("""foo""")+ −
+ −
val reg = """\d+""".r+ −
+ −
reg.findAllIn("bbbbaaabbbaaaccc").toList+ −
reg.replaceAllIn("bbbbaaabbbaaaccc", "*")+ −
reg.replaceAllIn("bbbb0aaa1bbba2aac3cc", "_")+ −
reg.replaceAllIn("bbbb00aaa11bbba232aac33cc", "_")+ −
+ −
+ −
// Further Information+ −
//=====================+ −
+ −
// The Scala homepage and general information is at+ −
//+ −
// http://www.scala-lang.org+ −
// http://docs.scala-lang.org+ −
//+ −
//+ −
// It should be fairly easy to install the Scala binary and+ −
// run Scala on the commandline. People also use Scala with + −
// Vim and Jedit. I currently settled on VS Code+ −
//+ −
// https://code.visualstudio.com+ −
//+ −
// There are also plugins for Eclipse and IntelliJ - YMMV.+ −
// Finally there are online editors specifically designed for + −
// running Scala applications (but do not blame me if you lose + −
// all what you typed in):+ −
//+ −
// https://scalafiddle.io + −
// https://scastie.scala-lang.org+ −
//+ −
//+ −
//+ −
// Scala Library Docs+ −
//====================+ −
//+ −
// http://www.scala-lang.org/api/current/+ −
//+ −
// Scala Tutorials+ −
//+ −
// http://docs.scala-lang.org/tutorials/+ −
//+ −
// There are also a massive number of Scala tutorials on youtube+ −
// and there are tons of books and free material. Google is your + −
// friend.+ −
+ −
+ −