scala without args is a Read-Eval-Print-Loop (REPL), similar to Scheme, Python, …
println("Hello, World!")
def fac(n: Int): BigInt = { if (n==0) 1 else n * fac(n - 1) }
{ val x = 5; x + 2 } A "block" yields the value of the last expresseion
sbt Simple Build Tool. Cf. make, ant
hello-world-println.scala
object HelloWorld {
def main(args: Array[String]) {
println("Hello, World!")
}
}
% 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 to java ClassName)
Hello, World!
() not []
while (a(i) < pivot) i += 1
for (i <- 0 until a.length) a(i) = util.Random.nextInt() % 100
val size = 20 scala inferred the type of size as integer
val assignment once only
for generator filter yield transformerExp
for {
queens <- placeQueens(k - 1)
column <- List.range(1, n + 1)
if isSafe(column, queens, 1)
}
yield
column :: queens
object CallBackEx {
def oncePerSecond(callback: () => Unit) {
while (true) { callback(); Thread sleep 1000 }
}
def timeFlies() {
println("time flies like an arrow...")
}
def main(args: Array[String]) {
oncePerSecond(timeFlies)
}
}
object CallBackExAnonymous {
def oncePerSecond(callback: () => Unit) {
while (true) { callback(); Thread sleep 1000 }
}
def main(args: Array[String]) {
oncePerSecond(() =>
println("time flies like an arrow..."))
}
}
timeFlies removed
() => println("time flies like an arrow...") is an anonymous
function
() => Unit Unit cf. void
class Complex(real: Double, imaginary: Double) {
def re = real
def im = imaginary
override def toString() =
"" + re + (if (im < 0) "" else "+") + im + "i"
}
re is a getter method with no arguments; parens omittable.
if-expression.
def <, >, …
Any is the super-type of all (other) types.
object v Java static
Boolean, Int, Long, Float, etc. are (built-in) classes/types.
break s or continue s in for loops
_, <-, :: (+ several more)
object, Unit, Any, Nil, None, Some(x)
case is used in different ways
Array, List
var x, y, z: Int = 0
val x, y, z: Int = 0 assigned one-time
++, or --; use instead +=1 or -=1
val !#%&*+-/:<=>?@\^|~ = 1 // all simple opchars val wordEndingInOpChars_!#%&*+-/:<=>?@\^|~ = 1 val !^©® = 1 // opchars and symbols val abcαβγ_!^©® = 1 // mixing unicode letters and symbols
(x + y*2) / (1 + 3*z)
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
class Reference[T] {
private var contents: T = _
def set(value: T) { contents = value }
def get: T = contents
}
false for Boolean, () for the
Unit type and null 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))
}
}
List("one", "two", "three", "four").foreach { name => new Thread { override def run() = { println("Thread " + name + " [" + this + "] says Hello World!") } }.start }
List( "one", "two", "three", "four" ) .
foreach {
name =>
new Thread {
override // needed
def run() = {
println(
"Thread " + name +
" [" + this + "] " +
"says Hello, World!"
)
}
}
. start
}
recvActor ! msg send a message msg to recvActor
def synchronized[A] (e: => A): A Executes e in mutex mode
def wait() Running thread suspend itself by waiting on a
signal. (Unrelated to Linux signals.)
def wait(msec: Long) As above, but waits at most msec milli-seconds.
def notify() Cooperate with a wait -ing process, and check its
condition C and inform. Even so, do while (!C) wait()
def notifyAll() How many being waken up: one in notify() and
all in notifyAll() Many subtleties. Look up the docs.
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 CEG 7370 Official Binary Semaphores (but not exactly). The above is implemented using a monitor.
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
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
}
Any is the super-type of all (other) types.
PartialFunction
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)
}
}
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
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
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
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
}
import scala.concurrent.ops._ val fut = future(someLengthyComputation) anotherLengthyComputation val y = f(fut()) + g(fut())
def future[A](p: => A): Unit => A = {
val result = new SyncVar[A]
fork { result.set(p) }
(() => result.get)
}
import scala.actors.Actor
List("one", "two", "three", "four").foreach {
name =>
new Actor {
override
def act() = {
println("Thread " + name + " says Hello World!")
}
}
.start
}
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")!
% 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 of typer.
% scalac -Xprint:all fileName.scala Check it out!
scala invokes java with Scala's libraries.
scala and scalac are shell scripts on Linux. 200+ lines. Differ
in just one line. On windows, scala.bat and scalac.bat
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.
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
classpath example
% scalac -classpath /usr/share/java/scala-swing.jar HelloGui.scala
% scala -classpath .:/usr/share/java/scala-swing.jar HelloWorld
% 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[]);
}