Multiparadigm
Programming in Scala
Adapted from presentation by
H. C. Cunningham and J. C.
Church University of
Mississipi
What is Multiparadigm
Programming?
Definition:
A multiparadigm programming language
provides “a framework in which
programmers can work in a variety of
styles, freely intermixing constructs from
different paradigms.” [Tim Budd]
Programming paradigms:
imperative versus declarative (e.g., functional,
logic)
other dimensions – object-oriented, component-
oriented, concurrency-oriented, etc.
CS3180 (Prasad) ScalaMulti 2
Why Learn Multiparadigm
Programming?
Tim Budd:
“Research results from the psychology of
programming indicate that expertise in
programming is far more strongly related to
the number of different programming styles
understood by an individual than it is the
number of years of experience in
programming.”
The “goal of multiparadigm computing is to
provide ... a number of different problem-
solving styles” so that a programmer can
“select a solution technique that best matches
the characteristics of the problem”.
CS3180 (Prasad) ScalaMulti 3
Why Teach Multiparadigm
Programming?
Contemporary imperative and object-
oriented languages increasingly have
functional programming features, e.g.,
• higher order functions (closures)
• list comprehensions
New explicitly multiparadigm (object-
oriented/functional) languages are
appearing, e.g.,
• Scala on the Java platform (and .Net in future)
• F# on the .Net platform
CS3180 (Prasad) ScalaMulti 4
Scala
Programming language developed by Martin
Odersky’s team at EPFL in Switzerland
Executes on the Java platform
Integrates with Java
Has growing usage (e.g., Twitter, Foursquare, and
Linkedin)
Multiparadigm language
Object-oriented (with generics and mixins)
Functional (similar to Haskell and SML)
Extensible (method calls as operators, currying,
closures, by-name parameters)
• Actor-based concurrency-oriented programming
• Language-oriented programming
Statically typed with Hindley-Milner type inference
CS3180 (Prasad) ScalaMulti 5
Why Scala?
(Coming from Java/C++)
Runs on the JVM
Can use any Java code in Scala
Almost as fast as Java (within 10%)
Much shorter code
Odersky reports 50% reduction in most code
over Java
Local type inference
Fewer errors
No Null Pointer problems
More flexibility
As many public classes per source file as you
want
Operator overloading
6
Scala References
Website [Link]
• Martin Odersky. Scala Tutorial for Java
Programmers.
• Martin Odersky. Scala By Example.
Martin Odersky, Lex Spoon, and Bill
Venners. Programming in Scala: A
Comprehensive Step-By-Step Guide, 2nd
Edition, Artima, Inc., 2010.
Books on Scala:
[Link]
CS3180 (Prasad) ScalaMulti 7
Scala object system
Class-based
Single inheritance
Can define singleton objects easily
(no need for static which is not
really OO)
Traits, compound types, and views
allow for more flexibility
8
Basic Scala
Use var to declare variables:
var x = 3;
x += 4;
Use val to declare values (final vars)
val y = 3;
y += 4; // error
Notice no types, but it is statically typed
var x = 3;
x = “hello world”; // error
Type annotations:
var x : Int = 3;
9
Functional Scala
Defining lambdas – nameless functions
val f = x :Int => x + 42; f : mapping :int ->
int
Closures! A way to haul around state
var y = 3;
val g = {x : Int => y += 1; x+y; }
Maps (and a cool way to do some functions)
List(1,2,3).map(_+10).foreach(println)
Filtering (and ranges!)
1 to 100 filter (_ % 7 == 3) foreach (println)
(Feels a bit like UNIX pipes?)
10
Defining Hello World
object HelloWorld {
def main(args: Array[String]){
println("Hey world!")
}
}
Singleton object named HelloWorld (also replaces
static methods and variables)
Method main defined (procedure)
Parameter args of type Array[String]
Array is generic class with type parameter
CS3180 (Prasad) ScalaMulti 11
Interpreting Hello World
> scala
This is a Scala shell.
Type in expressions to have them evaluated.
Type :help for more information.
scala> object HelloWorld {
| def main(args: Array[String]) {
| println("Hey world!")
| }
|}
defined module HelloWorld
scala> [Link](null)
Hey world!
unnamed0: Unit = ()
scala>:q
CS3180 (Prasad) ScalaMulti 12
Compiling & Executing
Hello World
> scalac [Link]
> scala HelloWorld
Hey world!
CS3180 (Prasad) ScalaMulti 13
Numbers are Objects
Consider expression
1 + 2 * 3 / x
Operators are method calls (like
Smalltalk)
Operator symbols are identifiers
Expression above is same as
(1).+(((2).*(3))./(x))
CS3180 (Prasad) ScalaMulti 14
Functions are Objects
object Timer {
def oncePerSecond(callback:() => Unit){
while (true) {
callback(); Thread sleep 1000
} // 1-arg method sleep used as operator
}
def welcome() {
println("Welcome to CS3180!")
}
def main(args: Array[String]) {
oncePerSecond(welcome)
}
}
CS3180 (Prasad) ScalaMulti 15
Timer Execution
scala> :l [Link]
Loading [Link]...
defined module Timer
scala> [Link](null)
Welcome to CS3180!
Welcome to CS3180!
Welcome to CS3180!
…
CS3180 (Prasad) ScalaMulti 16
Anonymous Functions
object Timer {
def oncePerSecond(callback:() => Unit){
while (true) {
callback(); Thread sleep 1000
}
}
def main(args: Array[String]) {
oncePerSecond(
() => println("Welcome to CS3180!") )
}
}
CS3180 (Prasad) ScalaMulti 17
Classes
class Complex(real: Double, imag: Double){
def re = real
def im = imag
}
Class primary constructor combined with class body
Parameters of class private constants within class
Parameterless methods re and im
Return types of re and im inferred from
expression (cannot be inferred for recursive
functions)
Thus more concise syntax
CS3180 (Prasad) ScalaMulti 18
Method Overriding
// [Link]
class Complex(real: Double, imag: Double) {
def re = real
def im = imag
override def toString =
re + (if (im < 0.0) "" else "+") +
im + ”I"
}
Classes extend class AnyRef by default
Methods must explicitly override parent method
if expressions
CS3180 (Prasad) ScalaMulti 19
Using Classes and Objects
scala> :load [Link]
Loading [Link]...
defined class Complex
scala> val x = new Complex(1,-3)
x: Complex = 1.0-3.0i
scala> [Link]
res0: [Link] = 1.0-3.0i
CS3180 (Prasad) ScalaMulti 20
Case Classes
abstract class Tree // Expression Trees
case class Sum(l: Tree, r: Tree)
extends Tree
case class Var(n: String) extends Tree
case class Const(v: int) extends Tree
Cf. Algebraic data types as in functional languages
Keyword new not needed to create instances (objects)
Getters defined automatically for constructor
parameters
Pattern matching can be used to decompose
equals method defined on structure of instances
CS3180 (Prasad) ScalaMulti 21
Pattern Matching
object Expressions {
type Environ = String => Int
def eval(t: Tree, env: Environ): Int = t match {
case Sum(l,r) => eval(l,env) + eval(r,env)
case Var(n) => env(n)
case Const(v) => v
}
def derive(t: Tree, v: String): Tree = t match {
case Sum(l,r) => Sum(derive(l,v),
derive(r,v))
case Var(n) if (v == n) => Const(1)
case _ => Const(0)
}
CS3180 (Prasad) ScalaMulti 22
Test Expression Trees
def main(args: Array[String]) {
val exp: Tree =
Sum(Sum(Var("x"),Var("x")),
Sum(Const(7),Var("y")))
val env: Environ =
{ case "x" => 5 case "y" => 7 }
println("Expression: " + exp)
println("Evaluation with x=5, y=7: " +
eval(exp,env))
println("Derivative relative to x:\n " +
derive(exp, "x"))
println("Derivative relative to y:\n " +
derive(exp, "y"))
}
}
CS3180 (Prasad) ScalaMulti 23
Execute Expression Trees
scala> :load [Link]
Loading [Link]...
…
scala> [Link](null)
Expression:
Sum(Sum(Var(x),Var(x)),Sum(Const(7),Var(y)))
Evaluation with x=5, y=7: 24
Derivative relative to x:
Sum(Sum(Const(1),Const(1)),Sum(Const(0),Const(0)))
Derivative relative to y:
Sum(Sum(Const(0),Const(0)),Sum(Const(0),Const(1)))
CS3180 (Prasad) ScalaMulti 24
Defs, Vals, and Vars
Three types of identifier definitions:
def defines functions with parameters; RHS
expression evaluated each time called
val defines unchanging values; RHS
expression evaluated immediately to
initialize
var defines storage location whose values
can be changed by assignment statements;
RHS expression evaluated immediately to
initialize
CS3180 (Prasad) ScalaMulti 25
Traits
trait Ord { // Order comparison operators
def < (that: Any): Boolean // abstract
def <=(that: Any): Boolean =
(this < that) || (this == that)
def > (that: Any): Boolean =
!(this <= that)
def >=(that: Any): Boolean =
!(this < that)
}
Like Java interfaces except can have concrete methods
Can be “mixed-in” to class
Note that < is abstract; others defined with < and
equals
CS3180 (Prasad) ScalaMulti 26
Date Class with Mixin Trait
Ord
class Date(y: Int, m: Int, d: Int)
extends Ord {
def year = y
def month = m
def day = d
override def toString(): String =
year + "-" + month + "-" + day
// … need definition of < and equals
}
Can only extend one class or trait
May mix-in additional classes using keyword with
CS3180 (Prasad) ScalaMulti 27
Date Class Equals Method
override def equals(that: Any): Boolean =
[Link][Date] && {
val o = [Link][Date]
[Link] == day && [Link] == month &&
[Link] == year
}
isInstanceOf[T] checks whether object is an
instance of the given type T
asInstanceOf[T] casts static type to T if
compatible with dynamic type of object
Value of last statement of function is returned
CS3180 (Prasad) ScalaMulti 28
Date Class < Method
def <(that: Any): Boolean = {
if (![Link][Date])
error("Cannot compare " + that +
" and a Date")
val o = [Link][Date]
(year < [Link]) ||
(year == [Link] &&
(month < [Link] ||
(month == [Link] && day < [Link])))
}
CS3180 (Prasad) ScalaMulti 29
DateTest
object DateTest {
def main(args: Array[String]) {
val x = new Date(1,1,2000)
val y = new Date(12,31,2001)
println("x = " + x)
println("y = " + y)
println("x < y: " + (x<y))
println("x > y: " + (x>y))
}
}
CS3180 (Prasad) ScalaMulti 30
DateTest Output
> scala DateTest
x = 1-1-2000
y = 12-31-2001
x < y: true
x > y: false
CS3180 (Prasad) ScalaMulti 31
Scala Functions
Are first-class values – i.e., functions are
objects
Can be higher-order – take functions as
arguments or return them as result
Can be anonymous
May be curried – take arguments one at a
time, allowing partial application
Are often passed in a closure – with
references to free variables they maninpulate
Provide ability to build powerful libraries of
higher-order functions
CS3180 (Prasad) ScalaMulti 32
Curried Functions
scala> def add(x: Int, y: Int) = x + y
add: (Int,Int)Int
scala> add(1,3)
res0: Int = 4
scala> def addc(x: Int)(y: Int) = x + y
addc: (Int)(Int)Int
scala> addc(1)(3)
res1: Int = 4
CS3180 (Prasad) ScalaMulti 33
Partial Application
scala> def addc(x: Int)(y: Int) = x + y
addc: (Int)(Int)Int
scala> val z = addc(1) _
z: (Int) => Int = <function>
scala> z(3)
res2: Int = 4
CS3180 (Prasad) ScalaMulti 34
Closures
scala> val inc = 10
inc: Int = 10
scala> def incre(x: Int) = x + inc
incre: (Int)Int
scala> def app(y: Int, g: (Int=>Int)) = g(y)
app: (Int,(Int) => Int)Int
scala> app(13,incre)
res0: Int = 23
CS3180 (Prasad) ScalaMulti 35
Using List Map
scala> val xs = List(3,4,5)
xs: List[Int] = List(3, 4, 5)
scala> val triples = [Link](x => 3*x)
triples: List[Int] = List(9, 12, 15)
scala> val evens = [Link](x => x%2==0)
evens: List[Int] = List(4)
CS3180 (Prasad) ScalaMulti 37
Other Higher Order List
Methods
flatMap
foldLeft, foldRight
reduceLeft, reduceRight
takeWhile, dropWhile
span, break
foreach
CS3180 (Prasad) ScalaMulti 39
For Comprehensions
scala> for(i <- 1 to 30;
| j <- List(2,3,5,7);
| if i % j == 0) yield (i,j)
res0: [Link][(Int, Int)] =
Vector((2,2), (3,3), (4,2), (5,5), (6,2),
(6,3), (7,7), (8,2), (9,3), (10,2), (10,5),
(12,2), (12,3), (14,2), (14,7), (15,3), (15,5),
(16,2),(18,2), (18,3), (20,2), (20,5), (21,3),
(21,7), (22,2), (24,2), (24,3), (25,5), (26,2),
(27,3), (28,2), (28,7), (30,2), (30,3), (30,5))
CS3180 (Prasad) ScalaMulti 40
Scala class hierarchy
Actors in Scala
CS3180 (Prasad) ScalaMulti 43
Motivation
Concurrency is hard!
Real World is parallel and distributed.
Erlang's notion of a process:
Concurrent processes should pass
messages to other processes rather than
share memory.
Erlang's processes are part of the
language.
Scala's actors are part of the library.
CS3180 (Prasad) ScalaMulti 44
Actors
Actors act independent of other
actors.
Actors have mailboxes.
Actors communicate by sending
messages to other actors.
Actors will check their mailbox and
react to their messages.
CS3180 (Prasad) ScalaMulti 45
Message in a Bottle
Any object can be sent to an Actor
case object myMessageObject
...
myActor ! myMessageObject
CS3180 (Prasad) ScalaMulti 46
Please Mr. Postman
How urgent is it?
react: I need it now!
receiveWithin: I need it soon!
receive: I'll wait.
All three methods will perform
pattern matching on the objects
received.
CS3180 (Prasad) ScalaMulti 47
Overacting
import [Link]._
object SillyActor extends Actor {
def act() { // Defines how our actor acts
for (i <- 1 to 5) {
println(“I'm acting!”)
[Link](1000)
}
}
}
...
[Link]() // Begins acting
CS3180 (Prasad) ScalaMulti 48
Vegetable Launcher
case object Tomato
case object Lettuce
object VegetableLauncher extends Actor {
def act() {
for (i <- 1 to 5) {
VegetableCatcher ! Tomato // Send it!
[Link](1000)
VegetableCatcher ! Lettuce // Send it!
[Link](1000)
}
}
}
CS3180 (Prasad) ScalaMulti 49
Vegetable Catcher
object VegetableCatcher extends Actor {
def act() {
loop {
react { // Non-blocking call
// Pattern Matching
case Lettuce =>
println("I caught a lettuce!")
case Tomato =>
println("I caught a tomato!")
}
}
}
}
CS3180 (Prasad) ScalaMulti 50
Lights, Camera, ...
[Link]()
[Link]()
[Link]()
I'm acting!
I caught a tomato!
I'm acting!
I caught a lettuce!
I'm acting!
I caught a tomato!
I'm acting!
I caught a lettuce!
I'm acting!
I caught a tomato!
I caught a lettuce!
I caught a tomato!
I caught a lettuce!
I caught a tomato!
I caught a lettuce!
CS3180 (Prasad) ScalaMulti 51