CEG 7370 | Actors Akka Scala Overview | Slides

A Practical Intro to Scala

Table of Contents

1 75 minutes or less?

  1. Obviously, in 75 minutes or less, we cannot make you an expert in Scala. But you will learn enough Scala to start writing programs involving actors – provided you
    1. have taken an OS course, and
    2. are fluent in Java.
  2. However, we defocus functional programming, and fancy features.
  3. Link to Source Code Examples: ./scalaExamples
  4. Martin Odersky and others, at EPFL, Switzerland, are the designers of Scala.
  5. Scala is still evolving: v 2.11.6 Mar 2015

2 Scala REPL interactive

  1. scala without args is a Read-Eval-Print-Loop (REPL), similar to Scheme, Python, …
  2. Try println("Hello, World!")
  3. Try def fac(n: Int): BigInt = { if (n==0) 1 else n * fac(n - 1) }
  4. Note the declaration style; the {} can be omitted
  5. Try { val x = 5; x + 2 } A "block" yields the value of the last expresseion
  6. Caution: Scala is a large language; a simple mistake can produce difficult to understand error.

3 Scala Tools

  1. sbt Simple Build Tool. Cf. make, ant
  2. Intellij IDEA plugin http://www.jetbrains.com/idea/features/scala.html
  3. Eclipse plugin http://scala-ide.org/
  4. http://www.scalatest.org/

3.1 scalac followed by scala

  1. content of file named hello-world-println.scala
    object HelloWorld {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
    
  2. % scalac hello-world-println.scala
  3. % 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
    
  4. % scala HelloWorld (similar to java ClassName)
    Hello, World!
    

4 Short Examples

4.1 Quick Sort (Layout of a Complete Prog)

  1. array indexing () not []
  2. while loop: while (a(i) < pivot) i += 1
  3. for loop:
    for (i <- 0 until a.length)
      a(i) = util.Random.nextInt() % 100
    
  4. val size = 20 scala inferred the type of size as integer
  5. val assignment once only
  6. source code ./scalaExamples/quickSort.scala

4.2 The N-Queens Problem (For-Comprehensions)

  1. 8-queens problem: Given a standard chess-board, place 8 queens so that no queen is in check from any other.
  2. For-Comprehensions stx: for generator filter yield transformerExp
  3. For-Comprehensions
    for { 
      queens <- placeQueens(k - 1)
      column <- List.range(1, n + 1)
      if isSafe(column, queens, 1) 
    }
    yield
      column :: queens
    
  4. source code ./scalaExamples/nqueens.scala

4.3 CallBack

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)
  }
}

4.4 CallBack, Anonymous

object CallBackExAnonymous {
  def oncePerSecond(callback: () => Unit) {
    while (true) { callback(); Thread sleep 1000 }
  }
  def main(args: Array[String]) {
    oncePerSecond(() =>
      println("time flies like an arrow..."))
  }
}
  1. Note timeFlies removed
  2. () => println("time flies like an arrow...") is an anonymous function
  3. Type inferred: () => Unit Unit cf. void

4.5 Classes, Inheritance and Overriding

class Complex(real: Double, imaginary: Double) {
  def re = real
  def im = imaginary
  override def toString() =
    "" + re + (if (im < 0) "" else "+") + im + "i"
}
  1. re is a getter method with no arguments; parens omittable.
  2. Note the embedded if-expression.

4.6 Traits

  1. Java has just single inheritance, and so uses multiple interfaces.
  2. Scala Traits are "partial" classes; they contain code for methods.
  3. A Scala class can import code from several traits.
  4. source code ./scalaExamples/traitEx.scala
  5. source code ./scalaExamples/compare.scala ; def <, >, …
  6. type Any is the super-type of all (other) types.

5 Scala cf. Java

  1. Scala object v Java static
  2. Boolean, Int, Long, Float, etc. are (built-in) classes/types.
  3. There are no break s or continue s in for loops

5.1 Tokens

  1. new special tokens: _, <-, :: (+ several more)
  2. object, Unit, Any, Nil, None, Some(x)
  3. case is used in different ways
  4. Constructors: Array, List
  5. var x, y, z: Int = 0
  6. val x, y, z: Int = 0 assigned one-time
  7. no ++, or --; use instead +=1 or -=1

5.1.1 Tokens-2

  1. Alphanumeric identifiers, Operator identifiers, Mixed identifiers
  2. (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
    

5.2 Case Classes and Pattern Matching

  1. Example expression: (x + y*2) / (1 + 3*z)
  2. 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
    
  3. ./scalaExamples/calc.scala source code for a complete program but without * and /

5.3 Genericity

  1. Genericity is the ability to write code where types can be substituted.
  2. class Reference[T] {
      private var contents: T = _
      def set(value: T) { contents = value }
      def get: T = contents
    }
    
  3. Here, the underscore stands for the default value (of type T). This default is 0 for numerics, false for Boolean, () for the Unit type and null for all object types.
  4. object IntegerReference {
      def main(args: Array[String]) {
        val cell = new Reference[Int]
        cell.set(13)
        println("Reference contains the half of " + (cell.get * 2))
      }
    }
    
  5. source code: ./scalaExamples/generics.scala

6 Concurrency in Scala

6.1 Threads

  1. Try this in scala REPL: List("one", "two", "three", "four").foreach { name => new Thread { override def run() = { println("Thread " + name + " [" + this + "] says Hello World!") } }.start }
  2. Next: same code as above but prettied up

6.2 Thread Example, prettied up

List( "one", "two", "three", "four" ) .
  foreach {
    name =>
      new Thread {
          override // needed
          def run() = {
            println(
             "Thread " + name +
             " [" + this + "] " +
             "says Hello, World!"
            )
          }
      }
      .  start
  }

6.3 Concurrency in Scala

  1. Scala can do Signals and Monitors, SyncVars, Futures, Parallel Computations, Semaphores, Readers/Writers, Asynchronous Channels, Synchronous Channels, Threads, Workers, Mailboxes, and Actors.
  2. recvActor ! msg send a message msg to recvActor

6.4 Signals and Monitors

  1. Read: Andrews, Chapter 6: Monitors.
  2. def synchronized[A] (e: => A): A Executes e in mutex mode
  3. def wait() Running thread suspend itself by waiting on a signal. (Unrelated to Linux signals.)
  4. def wait(msec: Long) As above, but waits at most msec milli-seconds.
  5. def notify() Cooperate with a wait -ing process, and check its condition C and inform. Even so, do while (!C) wait()
  6. def notifyAll() How many being waken up: one in notify() and all in notifyAll() Many subtleties. Look up the docs.

6.5 Semaphores

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.

6.6 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

6.7 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
}
  1. type Any is the super-type of all (other) types.
  2. PartialFunction

6.8 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)
  }
}

6.8.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

6.9 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

6.10 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

6.11 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
}
  1. API scala.concurrent.SyncVar

6.12 Futures

  1. An expression yet to be computed. In parallel with something else.
  2. Use
    import scala.concurrent.ops._
    
    val fut = future(someLengthyComputation)
    anotherLengthyComputation
    val y = f(fut()) + g(fut())
    
  3. API Futures
    def future[A](p: => A): Unit => A = {
      val result = new SyncVar[A]
      fork { result.set(p) }
      (() => result.get)
    }
    
  4. More on futures in akka

6.13 Hello Word with Actors

import scala.actors.Actor

List("one", "two", "three", "four").foreach {
 name =>
   new Actor {
     override
     def act() = {
       println("Thread " + name + " says Hello World!")
     }
   }
  .start
}
  1. NOte the use of import scala.actors.Actor
  2. scala.actors.- are about be deprecated.
  3. Use akka.actors
  4. read actors and akka

7 Scala can be Hard to Learn

  1. Voluminous documentation aimed at programming newbies. Too many (incompatible) versions. 24,066 questions tagged on http://stackoverflow.com/questions/tagged/scala
  2. Functional Programming paradigm: Imagine no variable can be assigned more than once. Anonymous Functions. Currying. Closures. Functions as first class values. Lazy values.
  3. Futures, Promises
  4. Type inferance; Co-variance and contra-variance; Monads
  5. Omission of "things": Implicit arguments, the dot, the semicolon, …

8 scala, scalac details

8.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")!

8.2 scalac options

  1. % scalac -help Print a synopsis of options.
  2. % scalac -X Print a synopsis of advanced options.
  3. % scalac -print pingObj-actor.scala Print program with Scala-specific features removed.
  4. % scalac -Xprint:typer fileName.scala Syntax trees at end of typer.
  5. % scalac -Xprint:all fileName.scala Check it out!

8.3 Scala Misc Info

  1. scala invokes java with Scala's libraries.
  2. scala and scalac are shell scripts on Linux. 200+ lines. Differ in just one line. On windows, scala.bat and scalac.bat
  3. 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.
    

8.4 Scala Misc Info-2

  1. bash:
    1. export SCALA_HOME=/usr/local/scala-2.11.0-RC3
    2. alias scala=/usr/local/scala-2.11.0-RC3/bin/scala
    3. alias scalac=/usr/local/scala-2.11.0-RC3/bin/scalac
    4. PATH=$PATH:$SCALA_HOME/bin
  2. scala classpath example
    1. % scalac -classpath /usr/share/java/scala-swing.jar HelloGui.scala
    2. % scala -classpath .:/usr/share/java/scala-swing.jar HelloWorld

8.5 Disassembly with javap

  1. % 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[]);
    }
    

9 References

  1. Link to Source Code Examples: ./scalaExamples
  2. https://typesafe.com/activator is the place for ready-to-compile -and-run examples of Scala (or Java) with Akka. Required Visit.
  3. Martin Odersky, "Scala by Example". A book by the designer of the language. Highly recommended read: Chapter 17: Abstractions for Concurrency (10+ pages). The full book is at http://www.scala-lang.org/docu/files/ScalaByExample.pdf, 150+ pages. June 2014. Despite the name of the book, only a few were ready-to-compile-and-run examples. Some of my slides are based on this book. Recommended Reading.
  4. Lewis, Laufer, and Thiruvathukal, "SIGCSE Workshop on Scala", March 2014, http://scalaworkshop.cs.luc.edu/latex/sigcse-scala.pdf; SIGCSE = ACM Special Interest Group on Computer Science Education. http://www.sigcse.org/ Recommended Reading.

9.1 References, contd

  1. Horstmann, Cay S. "Scala for the Impatient." Pearson Education, 2012. A legit pdf of the first 100+ pages is widely downloadable. "Currently the best compact introduction to Scala" – Martin Odersky. Recommended Reading.
  2. Martin Odersky, https://www.coursera.org/courses?search=scala The "Principles of Reactive Programming" is relevant to this course.
  3. Michel Schinz, Philipp Haller, "A Scala Tutorial for Java programmers", http://www.scala-lang.org/docu/files/ScalaTutorial.pdf, 2014, 15 pages. Some of my examples are from this booklet. Recommended Reading.
  4. Peter Sestoft, "Programs as Data; The Scala language, an overview", slides, Univ of Copenhagen, 2013. Some of my slides are adapted from here.
  5. Opinions: http://www.unlimitednovelty.com/2009/04/why-i-dont-like-scala.html; http://zeroturnaround.com/rebellabs/scala-sink-or-swim-part-1/ What to avoid in the Scala ecosystem. Do visit – after you learn enough Scala and Akka.

Copyright © 2015 pmateti@wright.edu www.wright.edu/~pmateti 2015-03-13