Multiparadigm Programming in Scala Adapted from presentation by

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. CS 3180 (Prasad) Scala. Multi 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”. CS 3180 (Prasad) Scala. Multi 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 (objectoriented/functional) languages are appearing, e. g. , • • Scala on the Java platform (and. Net in future) F# on the. Net platform CS 3180 (Prasad) Scala. Multi 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 CS 3180 (Prasad) Scala. Multi 5

Why Scala? (Coming from Java/C++) n n Runs on the JVM n Can use any Java code in Scala n Almost as fast as Java (within 10%) Much shorter code n Odersky reports 50% reduction in most code over Java n Local type inference Fewer errors n No Null Pointer problems More flexibility n As many public classes per source file as you want n Operator overloading 6

Scala References § Website http: //www. scala-lang. org • • 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, 2 nd Edition, Artima, Inc. , 2010. § Books on Scala: http: //www. scala-lang. org/node/959 CS 3180 (Prasad) Scala. Multi 7

Scala object system Class-based n Single inheritance n Can define singleton objects easily (no need for static which is not really OO) n Traits, compound types, and views allow for more flexibility n 8

Basic Scala n Use var to declare variables: var x = 3; x += 4; n Use val to declare values (final vars) val y = 3; y += 4; // error n Notice no types, but it is statically typed var x = 3; x = “hello world”; // error n Type annotations: var x : Int = 3; 9

Functional Scala n Defining lambdas – nameless functions val f = x : Int => x + 42; f : mapping : Int -> Int n Closures! A way to haul around state var y = 3; val g = {x : Int => y += 1; x+y; } n Maps (and a cool way to do some functions) List(1, 2, 3). map(_+10). foreach(println) n Filtering (and ranges!) 1 to 100 filter (_ % 7 == 3) foreach (println) n (Feels a bit like UNIX pipes? ) 10
![Defining Hello World object Hello. World { def main(args: Array[String]){ println("Hey world!") } } Defining Hello World object Hello. World { def main(args: Array[String]){ println("Hey world!") } }](http://slidetodoc.com/presentation_image_h2/4496afd1e24c91bf5d3386dfef9a0998/image-11.jpg)
Defining Hello World object Hello. World { def main(args: Array[String]){ println("Hey world!") } } § Singleton object named Hello. World (also replaces static methods and variables) § Method main defined (procedure) § Parameter args of type Array[String] § Array is generic class with type parameter CS 3180 (Prasad) Scala. Multi 11

Interpreting Hello World > scala This is a Scala shell. Type in expressions to have them evaluated. Type : help for more information. scala> object Hello. World { | def main(args: Array[String]) { | println("Hey world!") | } |} defined module Hello. World scala> Hello. World. main(null) Hey world! unnamed 0: Unit = () scala>: q CS 3180 (Prasad) Scala. Multi 12

Compiling & Executing Hello World > scalac Hello. World. scala > scala Hello. World Hey world! CS 3180 (Prasad) Scala. Multi 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)) CS 3180 (Prasad) Scala. Multi 14

Functions are Objects object Timer { def once. Per. Second(callback: () => Unit){ while (true) { callback(); Thread sleep 1000 } // 1 -arg method sleep used as operator } def welcome() { println("Welcome to CS 3180!") } def main(args: Array[String]) { once. Per. Second(welcome) } } CS 3180 (Prasad) Scala. Multi 15

Timer Execution scala> : l Timer. scala Loading Timer. scala. . . defined module Timer scala> Timer. main(null) Welcome to CS 3180! … CS 3180 (Prasad) Scala. Multi 16

Anonymous Functions object Timer { def once. Per. Second(callback: () => Unit){ while (true) { callback(); Thread sleep 1000 } } def main(args: Array[String]) { once. Per. Second( () => println("Welcome to CS 3180!") ) } } CS 3180 (Prasad) Scala. Multi 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 CS 3180 (Prasad) Scala. Multi 18

Method Overriding // Complex. scala class Complex(real: Double, imag: Double) { def re = real def im = imag override def to. String = re + (if (im < 0. 0) "-" else "+") + im + “i" } § Classes extend class Any. Ref by default § Methods must explicitly override parent method § if expressions CS 3180 (Prasad) Scala. Multi 19

Using Classes and Objects scala> : load Complex. scala Loading Complex. scala. . . defined class Complex scala> val x = new Complex(1, -3) x: Complex = 1. 0 -3. 0 i scala> x. to. String res 0: java. lang. String = 1. 0 -3. 0 i CS 3180 (Prasad) Scala. Multi 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 CS 3180 (Prasad) Scala. Multi 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) } CS 3180 (Prasad) Scala. Multi 22
![Test Expression Trees def main(args: Array[String]) { val exp: Tree = Sum(Var("x"), Var("x")), Sum(Const(7), Test Expression Trees def main(args: Array[String]) { val exp: Tree = Sum(Var("x"), Var("x")), Sum(Const(7),](http://slidetodoc.com/presentation_image_h2/4496afd1e24c91bf5d3386dfef9a0998/image-23.jpg)
Test Expression Trees def main(args: Array[String]) { val exp: Tree = 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")) } } CS 3180 (Prasad) Scala. Multi 23

Execute Expression Trees scala> : load Expressions. scala Loading Expressions. scala. . . … scala> Expressions. main(null) Expression: Sum(Var(x), Var(x)), Sum(Const(7), Var(y))) Evaluation with x=5, y=7: 24 Derivative relative to x: Sum(Const(1), Const(1)), Sum(Const(0), Const(0))) Derivative relative to y: Sum(Const(0), Const(0)), Sum(Const(0), Const(1))) CS 3180 (Prasad) Scala. Multi 24

Defs, Vals, and Vars Three types of identifier definitions: defines functions with parameters; RHS expression evaluated each time it is 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 CS 3180 (Prasad) Scala. Multi 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 CS 3180 (Prasad) Scala. Multi 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 to. String(): String = year + "-" + month + "-" + day // … need definition of < and equals } § § Can only extend one class or trait May mix-in additional classes using keyword with CS 3180 (Prasad) Scala. Multi 27
![Date Class Equals Method override def equals(that: Any): Boolean = that. is. Instance. Of[Date] Date Class Equals Method override def equals(that: Any): Boolean = that. is. Instance. Of[Date]](http://slidetodoc.com/presentation_image_h2/4496afd1e24c91bf5d3386dfef9a0998/image-28.jpg)
Date Class Equals Method override def equals(that: Any): Boolean = that. is. Instance. Of[Date] && { val o = that. as. Instance. Of[Date] o. day == day && o. month == month && o. year == year } § § § is. Instance. Of[T] checks whether object is an instance of the given type T as. Instance. Of[T] casts static type to T if compatible with dynamic type of object Value of last statement of function is returned CS 3180 (Prasad) Scala. Multi 28

Date Class < Method def <(that: Any): Boolean = { if (!that. is. Instance. Of[Date]) error("Cannot compare " + that + " and a Date") val o = that. as. Instance. Of[Date] (year < o. year) || (year == o. year && (month < o. month || (month == o. month && day < o. day))) } CS 3180 (Prasad) Scala. Multi 29
![Date. Test object Date. Test { def main(args: Array[String]) { val x = new Date. Test object Date. Test { def main(args: Array[String]) { val x = new](http://slidetodoc.com/presentation_image_h2/4496afd1e24c91bf5d3386dfef9a0998/image-30.jpg)
Date. Test object Date. Test { 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)) } } CS 3180 (Prasad) Scala. Multi 30

Date. Test Output > x y x x scala Date. Test = 1 -1 -2000 = 12 -31 -2001 < y: true > y: false CS 3180 (Prasad) Scala. Multi 31

Scala Functions § § § Are first-class values – i. e. , functions are objects Can be higher-order – take functions as arguments and/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 manipulate Provide ability to build powerful libraries of higher-order functions CS 3180 (Prasad) Scala. Multi 32

Curried Functions scala> def add(x: Int, y: Int) = x + y add: (Int, Int)Int scala> add(1, 3) res 0: Int = 4 scala> def addc(x: Int)(y: Int) = x + y addc: (Int)Int scala> addc(1)(3) res 1: Int = 4 CS 3180 (Prasad) Scala. Multi 33

Partial Application scala> def addc(x: Int)(y: Int) = x + y addc: (Int)Int scala> val z = addc(1) _ z: (Int) => Int = <function> scala> z(3) res 2: Int = 4 CS 3180 (Prasad) Scala. Multi 34

Closures scala> val inc = 10 inc: Int = 10 scala> def incre(x: Int) = x + incre: (Int)Int scala> def app(y: Int, g: (Int=>Int)) = g(y) app: (Int, (Int) => Int)Int scala> app(13, incre) res 0: Int = 23 CS 3180 (Prasad) Scala. Multi 35
![Using List Map scala> val xs = List(3, 4, 5) xs: List[Int] = List(3, Using List Map scala> val xs = List(3, 4, 5) xs: List[Int] = List(3,](http://slidetodoc.com/presentation_image_h2/4496afd1e24c91bf5d3386dfef9a0998/image-36.jpg)
Using List Map scala> val xs = List(3, 4, 5) xs: List[Int] = List(3, 4, 5) scala> val triples = xs. map(x => 3*x) triples: List[Int] = List(9, 12, 15) scala> val evens = xs. filter(x => x%2==0) evens: List[Int] = List(4) CS 3180 (Prasad) Scala. Multi 37

Other Higher Order List Methods § flat. Map § fold. Left, fold. Right § reduce. Left, reduce. Right § take. While, drop. While § span, break § foreach CS 3180 (Prasad) Scala. Multi 39

For Comprehensions scala> for(i <| j <| if i n 1 to 30; List(2, 3, 5, 7); % j == 0) yield (i, j) res 0: scala. collection. immutable. Indexed. Seq[(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, 3), (20, 2), (20, 5), (21, 3), (21, 7), (22, 2), (24, 3), (25, 5), (26, 2), (27, 3), (28, 2), (28, 7), (30, 2), (30, 3), (30, 5)) CS 3180 (Prasad) Scala. Multi 40

Scala class hierarchy

Actors in Scala CS 3180 (Prasad) Scala. Multi 43

Motivation Concurrency is hard! n Real World is parallel and distributed. n Erlang's notion of a process: n n Concurrent processes should pass messages to other processes rather than share memory. Erlang's processes are part of the language. n Scala's actors are part of the library. n CS 3180 (Prasad) Scala. Multi 44

Actors act independent of other actors. n Actors have mailboxes. n Actors communicate by sending messages to other actors. n Actors will check their mailbox and react to their messages. n CS 3180 (Prasad) Scala. Multi 45

Message in a Bottle n Any object can be sent to an Actor case object my. Message. Object. . . my. Actor ! my. Message. Object CS 3180 (Prasad) Scala. Multi 46

Please Mr. Postman n How urgent is it? react: I need it now! n receive. Within: I need it soon! n receive: I'll wait. n n All three methods will perform pattern matching on the objects received. CS 3180 (Prasad) Scala. Multi 47

Overacting import scala. actors. _ object Silly. Actor extends Actor { def act() { // Defines how our actor acts for (i <- 1 to 5) { println(“I'm acting!”) Thread. sleep(1000) } } }. . . Silly. Actor. start() // Begins acting CS 3180 (Prasad) Scala. Multi 48

Vegetable Launcher case object Tomato case object Lettuce object Vegetable. Launcher extends Actor { def act() { for (i <- 1 to 5) { Vegetable. Catcher ! Tomato // Send it! Thread. sleep(1000) Vegetable. Catcher ! Lettuce // Send it! Thread. sleep(1000) } } } CS 3180 (Prasad) Scala. Multi 49

Vegetable Catcher object Vegetable. Catcher 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!") } } CS 3180 (Prasad) Scala. Multi 50

Lights, Camera, . . . Vegetable. Launcher. start() Vegetable. Catcher. start() Silly. Actor. start() 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! CS 3180 (Prasad) Scala. Multi 51
- Slides: 48