A Practical Intro to Scala
Table of Contents
WIP Being revised. TBD Check links.
1 Scala Tutorial in Five Pages
- Scala is a "large" language. It has built-in support for functional and procedural programming, OOP, and concurrency. Its compilers can generate JVM as well as TBD native machine code.
- In 5 pages we cannot make you an expert in Scala. But you will learn enough Scala to start writing concurrent programs – provided you have taken an OS-level Concurrent Prog course, and are fluent in Java.
- We will use "actors" and Akka in this course. See ../../Actors.
- Page 1:
2 Scala Tutorial in 75 minutes
- How? We defocus functional programming, and fancy features.
- Link to Source Code Examples: ./scalaExamples
3 Scala REPL interactive
scalawithout args is a Read-Eval-Print-Loop (REPL), similar to Scheme, Python, …- Try
println("Hello, World!") - Try
def fac(n: Int): BigInt = { if (n==0) 1 else n * fac(n - 1) } - Note the declaration style; the {} can be omitted
- Try
{ val x = 5; x + 2 }A "block" yields the value of the last expresseion - Caution: Scala is a large language; a simple mistake can produce difficult to understand error.
4 Scala Tools
sbthttps://www.scala-sbt.org/ Simple Build Tool. Cf.make,ant- Intellij IDEA plugin http://www.jetbrains.com/idea/features/scala.html
- http://www.scalatest.org/
content of file named
hello-world-println.scalaobject HelloWorld { def main(args: Array[String]) { println("Hello, World!") } }- Compile
% scalac hello-world-println.scala % ls -ototal 16 -rw-rw-r-- 1 pmateti 595 Mar 29 21:26 HelloWorld.class -rw-rw-r-- 1 pmateti 608 Mar 29 21:26 HelloWorld$.class -rw-rw-r-- 1 pmateti 90 Mar 29 21:21 hello-world-println.scala
% scala HelloWorld(similar tojava ClassName)Hello, World!
5 Concurrency in Scala
- Scala can do the following whose descriptions you must have run into in the concurrent/ distributed programming literature: Signals and Monitors, SyncVars, Futures, Parallel Computations, Semaphores, Readers/Writers, Asynchronous Channels, Synchronous Channels, Threads, Workers, Mailboxes, and Actors.
5.1 Thread Example
Try this in Scala REPL
List( "one", "two", "three", "four" ) . foreach { name => new Thread { override // needed def run() = { println( "Thread " + name + " [" + this + "] " + "says Hello, World!" ) } } . start }
5.2 Signals and Monitors
- Read: Andrews, Chapter 6: Monitors.
def synchronized[A] (e: => A): AExecutesein mutex modedef wait()Running thread suspends itself by waiting on a signal. (Unrelated to Linux signals.)def wait(msec: Long)As above, but waits at mostmsecmilli-seconds.def notify()Cooperate with await-ing process, and check its conditionCand inform. Even so, dowhile (!C) wait()def notifyAll()How many being waken up: one innotify()and all innotifyAll()Many subtleties. Look up the docs.
5.3 Semaphores
We had a pristine description of what semaphores are. Scala semaphores are close, but no cigar.
package scala.concurrent class Lock { var available = true def acquire = synchronized { while (!available) wait() available = false } def release = synchronized { available = true notify() } }- Similar to our DC Official Binary Semaphores (but not exactly). The above is implemented using a monitor.
5.4 Bounded Buffers / Producers-Consumers
class BoundedBuffer(N: Int) {
val buf = new Array[Int](N)
var in, out = 0 // indices of buf
var n = 0 // #items in buf
def put(x: Int) = synchronized {
while (n >= N) { println("buf full") ; wait() }
buf(in) = x ; in = (in + 1) % N ; n += 1
if (n == 1) notifyAll() }
def get: Int = synchronized {
while (n == 0) wait()
val x = buf(out) ; out = (out + 1) % N ; n -= 1
if (n == N - 1) notifyAll()
x }
}
complete source: ./scalaExamples/bounded-buffers.scala
5.5 Mailboxes
class MailBox {
def send(msg: Any) synchronized { ... }
def receive[A](f: PartialFunction[Any, A]): A // uses synchronized { ... }
def receiveWithin[A](msec: Long)(f: PartialFunction[Any, A]): A
}
- type
Anyis the super-type of all (other) types. PartialFunction
5.6 Readers/Writers
class ReadersWriters {
val m = new MailBox
private case class Writers(n: Int) { m send this }
private case class Readers(n: Int) { m send this }
Writers(0); Readers(0)
// see slide (down-arrow) also
def endRead = m receive { // dot omitted
case Readers(n) => Readers(n-1)
}
def endWrite = m receive {
case Writers(n) => Writers(n-1)
if (n == 0) Readers(0)
}
}
5.6.1 Readers/Writers, contd
def startRead = m receive {
case Writers(n) if n == 0 => m receive {
case Readers(n) => Writers(0); Readers(n+1)
}
}
def startWrite = m receive {
case Writers(n) =>
Writers(n+1)
m receive { case Readers(n) if n == 0 => }
}
TBD URL to CEG 7370 Readers/Writers with priority for writers
5.7 Asynchronous Channels
class Channel[A] {
private var written = new LinkedList[A]
private var lastWritten = written
private var nreaders = 0
def write(x: A) = synchronized {
lastWritten.elem = x
lastWritten.next = new LinkedList[A]
lastWritten = lastWritten.next
if (nreaders > 0) notify() }
def read: A = synchronized {
if (written.next == null) {
nreaders += 1; wait(); nreaders -= 1
}
val x = written.elem
written = written.next
x }
}
API scala.concurrent.package; cf. CEG 7370 Semi AMP
5.8 Synchronous Channels
class SyncChannel[A] {
private var data: A = _
private var reading = false
private var writing = false
def write(x: A) = synchronized {
while (writing) wait()
data = x
writing = true
if (reading) notifyAll()
else while (!reading) wait()
}
def read: A = synchronized {
while (reading) wait()
reading = true
while (!writing) wait()
val x = data
writing = false
reading = false
notifyAll()
x
}
}
API scala.concurrent.package; cf. CEG 7370 SMP
5.9 SyncVars
package scala.concurrent
class SyncVar[A] {
private var isDefined: Boolean = false
private var v: A = _
def get = synchronized
{while (!isDefined) wait(); v}
def set(x: A) = synchronized
{v = x; isDefined=true; notifyAll()}
def isSet: Boolean = synchronized {isDefined}
def unset = synchronized {isDefined = false} // API
}
5.10 Futures
- An expression yet to be computed. In the future. When possible. When needed. In parallel with something else.
Use
import scala.concurrent.ops._ val fut = future(someLengthyComputation) anotherLengthyComputation val y = f(fut()) + g(fut())
API Futures
def future[A](p: => A): Unit => A = { val result = new SyncVar[A] fork { result.set(p) } (() => result.get) }- More on futures in akka
6 Functional
- Functions are first class values. Can be given as arguments. Can be computed and returned also.
- Main strength of Scala is its combo of OO and Functional
- Closures
- Futures
- Promises
7 Misc
- var alst: List[ActorRef] = List();
- dependency injection frameworks? Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 5 and above, brought to you by Google.
- http://docs.scala-lang.org/overviews/core/futures.html
- "Scala’s for loops are compiled to higher-order function calls, but while loops are low-level as in Java or C. … Concurrency and correctness might be easier to achieve with more functional code."
8 Scala cf. Java
- Scala
objectv Javastatic Boolean,Int,Long,Float, etc. are (built-in) classes/types.- There are no
breaks orcontinues inforloops
8.1 Tokens
- Identifiers, operators, … as in most languages.
- ! ? with Hoare's CSP semantics.
recvActor ! msgsend a message msg to recvActor- Unusual symbolic tokens:
::=:, :+ and :\ TBD - new special tokens:
_,<-,::(+ several more) object,Unit,Any,Nil,None,Some(x)caseis used in different ways- Constructors:
Array,List var x, y, z: Int = 0val x, y, z: Int = 0assigned one-time- no
++, or--; use instead+=1or-=1
8.1.1 Tokens-2
- Alphanumeric identifiers, Operator identifiers, Mixed identifiers
(from stackOverFlow.com ) Here are some valid examples:
val !#%&*+-/:<=>?@\^|~ = 1 // all simple opchars val wordEndingInOpChars_!#%&*+-/:<=>?@\^|~ = 1 val !^©® = 1 // opchars and symbols val abcαβγ_!^©® = 1 // mixing unicode letters and symbols
8.2 Case Classes and Pattern Matching
- Example expression:
(x + y*2) / (1 + 3*z) Develop a tree representation for use in a Calc program.
abstract class Tree case class Sum(l: Tree, r: Tree) extends Tree case class Var(n: String) extends Tree case class Const(v: Int) extends Tree
- ./scalaExamples/calc.scala source code for a complete program but without * and /
8.3 Genericity
- Genericity is the ability to write code where types can be substituted.
class Reference[T] { private var contents: T = _ def set(value: T) { contents = value } def get: T = contents }- Here, the underscore stands for the default value (of type T).
This default is 0 for numerics,
falsefor Boolean,()for theUnittype andnullfor all object types. object IntegerReference { def main(args: Array[String]) { val cell = new Reference[Int] cell.set(13) println("Reference contains the half of " + (cell.get * 2)) } }- source code: ./scalaExamples/generics.scala
8.4 (Dis) Similar to Java
toString- Cf Scala
traitsv Javainterfaces - Java
staticv Scalaobject
8.5 Dont Use
- Implicit arguments
9 Scala can be Hard to Learn
- Voluminous documentation aimed at programming newbies. Too many (incompatible) versions. E.g., 94,218 questions tagged on http://stackoverflow.com/questions/tagged/scala as of Dec 2019.
- Functional Programming paradigm: Imagine no variable can be assigned more than once. Anonymous Functions. Currying. Closures. Functions as first class values. Lazy values.
- Futures, Promises
- Type inferance; Co-variance and contra-variance; Monads
- Omission of "things": Implicit arguments, the dot, the semicolon, …
10 scala, scalac details
10.1 Execute External Program
import scala.sys.process._
val cmd = "/usr/local/scala-2.11.0-RC3/bin/scalac -help"
val txt = cmd.!! // captures stdout
val i : Int = Process("ls -l")!
10.2 scalac options
% scalac -helpPrint a synopsis of options.% scalac -XPrint a synopsis of advanced options.% scalac -print pingObj-actor.scalaPrint program with Scala-specific features removed.% scalac -Xprint:typer fileName.scalaSyntax trees at end oftyper.% scalac -Xprint:all fileName.scalaCheck it out!
10.3 Scala Misc Info
scalainvokesjavawith Scala's libraries.scalaandscalacare shell scripts on Linux. 200+ lines. Differ in just one line. On windows,scala.batandscalac.batScala version I am using [date: Mar 30, 2014] is
Welcome to Scala version 2.11.0-RC3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0). Type in expressions to have them evaluated. Type :help for more information.
10.4 Scala Misc Info-2
- bash:
export SCALA_HOME=/usr/local/scala-2.11.0-RC3alias scala=/usr/local/scala-2.11.0-RC3/bin/scalaalias scalac=/usr/local/scala-2.11.0-RC3/bin/scalacPATH=$PATH:$SCALA_HOME/bin
- scala
classpathexample% scalac -classpath /usr/share/java/scala-swing.jar HelloGui.scala% scala -classpath .:/usr/share/java/scala-swing.jar HelloWorld
10.5 Disassembly with javap
% javap HelloWorld.class HelloWorld\$.classCompiled from "hello-world-println.scala" public final class HelloWorld { public static void main(java.lang.String[]); } Compiled from "hello-world-println.scala" public final class HelloWorld$ { public static final HelloWorld$ MODULE$; public static {}; public void main(java.lang.String[]); }
11 References
- Link to Source Code Examples: ./scalaExamples
- https://scala-lang.org/documentation/learn.html Learning Resources.
- https://typesafe.com/activator is the place for ready-to-compile -and-run examples of Scala (or Java) with Akka. TypeSafe became https://www.lightbend.com/. Required Visit.
- Martin Odersky, "Scala by Example". {pmateti: A PDF book by the designer of the language. Highly recommended read: Chapter 17: Abstractions for Concurrency (10+ pages). Web search for the full book with ScalaByExample.pdf, 150+ pages. Latest build I have seen: June 2014. Despite the name of the book, only a few were ready-to-compile-and-run examples.}
- Martin Odersky, Philippe Altherr, Vincent Cremet, Iulian Dragos, Gilles Dubochet, Burak Emir, Sean McDirmid, Stéphane Micheloud, Nikolay Mihaylov, Michel Schinz, Erik Stenman, Lex Spoon, Matthias Zenger, An Overview of the Scala Programming Language, Second Edition, École Polytechnique Fédérale de Lausanne (EPFL) Technical Report LAMP-REPORT-2006-001 ["Official Ref"] https://www.scala-lang.org/docu/files/ScalaOverview.pdf
11.1 References #2
- http://www.flotsam.nl/dispatch-periodic-table.html "All operators of Scala's marvelous Dispatch library on a single page."
- https://airtable.com/shrDCOpnMP8iA6kOn 2019 Scala Developer Survey
- https://people.cs.ksu.edu/~schmidt/705a/Scala/
- https://scastie.scala-lang.org/ Scastie is Scala + sbt in your browser!
- https://developer.lightbend.com/start/
- Intellij IDEA for Scala