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
scala
without 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
sbt
https://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.scala
object HelloWorld { def main(args: Array[String]) { println("Hello, World!") } }
- Compile
% scalac hello-world-println.scala
% ls -o
total 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): A
Executese
in 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 mostmsec
milli-seconds.def notify()
Cooperate with await
-ing process, and check its conditionC
and 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
Any
is 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
object
v Javastatic
Boolean
,Int
,Long
,Float
, etc. are (built-in) classes/types.- There are no
break
s orcontinue
s infor
loops
8.1 Tokens
- Identifiers, operators, … as in most languages.
- ! ? with Hoare's CSP semantics.
recvActor ! msg
send a message msg to recvActor- Unusual symbolic tokens:
::=
:
, :+ and :\ TBD - new special tokens:
_
,<-
,::
(+ several more) object
,Unit
,Any
,Nil
,None
,Some(x)
case
is used in different ways- Constructors:
Array
,List
var x, y, z: Int = 0
val x, y, z: Int = 0
assigned one-time- no
++
, or--
; use instead+=1
or-=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,
false
for Boolean,()
for theUnit
type andnull
for 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
traits
v Javainterfaces
- Java
static
v 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 -help
Print a synopsis of options.% scalac -X
Print a synopsis of advanced options.% scalac -print pingObj-actor.scala
Print program with Scala-specific features removed.% scalac -Xprint:typer fileName.scala
Syntax trees at end oftyper
.% scalac -Xprint:all fileName.scala
Check it out!
10.3 Scala Misc Info
scala
invokesjava
with Scala's libraries.scala
andscalac
are shell scripts on Linux. 200+ lines. Differ in just one line. On windows,scala.bat
andscalac.bat
Scala 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-RC3
alias scala=/usr/local/scala-2.11.0-RC3/bin/scala
alias scalac=/usr/local/scala-2.11.0-RC3/bin/scalac
PATH=$PATH:$SCALA_HOME/bin
- scala
classpath
example% 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\$.class
Compiled 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