Scala: How to make best use of functions and objects Philipp Haller Lukas Rytz Martin Odersky EPFL ACM Symposium on Applied Computing Tutorial.

Slides:



Advertisements
Similar presentations
OO Programming in Java Objectives for today: Overriding the toString() method Polymorphism & Dynamic Binding Interfaces Packages and Class Path.
Advertisements

Portability and Safety Mahdi Milani Fard Dec, 2006 Java.
Scala: How to make best use of functions and objects Phillip Haller Lukas Rytz Martin Odersky EPFL ACM Symposium on Applied Computing Tutorial.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
George Blank University Lecturer. CS 602 Java and the Web Object Oriented Software Development Using Java Chapter 4.
Road Map Introduction to object oriented programming. Classes
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
OOP in Java Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Introduction to Java CS 331. Introduction Present the syntax of Java Introduce the Java API Demonstrate how to build –stand-alone Java programs –Java.
1 Gentle Introduction to Programming Session 5: Memory Model, Object Oriented Programming.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
Data Abstraction and Object- Oriented Programming CS351 – Programming Paradigms.
C++ fundamentals.
JAVA: An Introduction to Problem Solving & Programming, 5 th Ed. By Walter Savitch and Frank Carrano. ISBN © 2008 Pearson Education, Inc., Upper.
Starting Chapter 4 Starting. 1 Course Outline* Covered in first half until Dr. Li takes over. JAVA and OO: Review what is Object Oriented Programming.
Week 4-5 Java Programming. Loops What is a loop? Loop is code that repeats itself a certain number of times There are two types of loops: For loop Used.
The Scala Experience Martin Odersky EPFL Lausanne, Switzerland.
Introduction to Java Appendix A. Appendix A: Introduction to Java2 Chapter Objectives To understand the essentials of object-oriented programming in Java.
5.1 and 5.4 through 5.6 Various Things. Terminology Identifiers: a name representing a variable, class name, method name, etc. Operand: a named memory.
Imperative Programming
Chapter 3 Introduction to Collections – Stacks Modified
Introduction to Object Oriented Programming. Object Oriented Programming Technique used to develop programs revolving around the real world entities In.
The Scala Programming Language
The Scala Programming Language presented by Donna Malayeri.
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
Scala Overview Brandon Clopton CSCI 431. Scala fuses object-oriented and functional programming in a statically typed programming language. It is aimed.
Introduction to Scala Lecture 1 CMSC 331 SD Vick.
CSCI-383 Object-Oriented Programming & Design Lecture 13.
APCS Java AB 2004 Review of CS1 and CS2 Review for AP test #1 Sources: 2003 Workshop notes from Chris Nevison (Colgate University) AP Study Guide to go.
Hello.java Program Output 1 public class Hello { 2 public static void main( String [] args ) 3 { 4 System.out.println( “Hello!" ); 5 } // end method main.
Object-Oriented Program Development Using Java: A Class-Centered Approach, Enhanced Edition.
- Neeraj Chandra.  It’s language written by by Martin Odersky at EPFL  It’s language written by by Martin Odersky at EPFL (École Polytechnique Fédérale.
More on Hierarchies 1. When an object of a subclass is instantiated, is memory allocated for only the data members of the subclass or also for the members.
Java 5 Part 1 CSE301 University of Sunderland Harry Erwin, PhD.
Functional Programming With examples in F#. Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands.
Objects & Dynamic Dispatch CSE 413 Autumn Plan We’ve learned a great deal about functional and object-oriented programming Now,  Look at semantics.
Data TypestMyn1 Data Types The type of a variable is not set by the programmer; rather, it is decided at runtime by PHP depending on the context in which.
Recap form last time How to do for loops map, filter, reduce Next up: dictionaries.
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
Object Oriented Software Development
Chapter 10 Defining Classes. The Internal Structure of Classes and Objects Object – collection of data and operations, in which the data can be accessed.
Programming with Java © 2002 The McGraw-Hill Companies, Inc. All rights reserved. 1 McGraw-Hill/Irwin Chapter 5 Creating Classes.
Inheritance. Inheritance - Introduction Idea behind is to create new classes that are built on existing classes – you reuse the methods and fields and.
CS162 Week 1 Kyle Dewey. Overview Basic Introduction CS Accounts Scala survival guide.
Object-Oriented Programming Chapter Chapter
M1G Introduction to Programming 2 5. Completing the program.
Object Oriented Programming
Chapter 8 Class Inheritance and Interfaces F Superclasses and Subclasses  Keywords: super F Overriding methods  The Object Class  Modifiers: protected,
 In the java programming language, a keyword is one of 50 reserved words which have a predefined meaning in the language; because of this,
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Inheritance and Class Hierarchies Chapter 3. Chapter Objectives  To understand inheritance and how it facilitates code reuse  To understand how Java.
Chapter 11: Advanced Inheritance Concepts. Objectives Create and use abstract classes Use dynamic method binding Create arrays of subclass objects Use.
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
JAVA: An Introduction to Problem Solving & Programming, 6 th Ed. By Walter Savitch ISBN © 2012 Pearson Education, Inc., Upper Saddle River,
Terms and Rules II Professor Evan Korth New York University (All rights reserved)
OOP Basics Classes & Methods (c) IDMS/SQL News
CSE 341 Section 10 Subtyping, Review, and The Future.
CSC 243 – Java Programming, Spring, 2014 Week 4, Interfaces, Derived Classes, and Abstract Classes.
An Overview of Scala Philipp Haller, EPFL (Lots of things taken from Martin Odersky's Scala talks)
SCALA CONCEPTS PROGRAMMING USING FUNCTIONAL OBJECTS UMBC CMSC 331
Types CSCE 314 Spring 2016.
Introduction to Scala SD Vick 1.
Java Primer 1: Types, Classes and Operators
CS 326 Programming Languages, Concepts and Implementation
Functional Programming with Java
Martin Odersky EPFL Lausanne, Switzerland
Object Oriented Programming (OOP) LAB # 8
Java Programming Language
FP Foundations, Scheme In Text: Chapter 14.
Presentation transcript:

Scala: How to make best use of functions and objects Philipp Haller Lukas Rytz Martin Odersky EPFL ACM Symposium on Applied Computing Tutorial

2 Where it comes from Scala has established itself as one of the main alternative languages on the JVM. Prehistory: 1996 – 1997: Pizza 1998 – 2000: GJ, Java generics, javac ( “make Java better” ) Timeline: 2003 – 2006: The Scala “Experiment” 2006 – 2009: An industrial strength programming language ( “make a better Java” ) Розподілені обчислення

Розподілені обчислення

4 Why Scala? Розподілені обчислення

5 Scala is a Unifier Agile, with lightweight syntax Object-Oriented Scala Functional Safe and performant, with strong static typing Розподілені обчислення

6 What others say: Розподілені обчислення

7 “If I were to pick a language to use today other than Java, it would be Scala.” - James Gosling, creator of Java “Scala, it must be stated, is the current heir apparent to the Java throne. No other language on the JVM seems as capable of being a "replacement for Java" as Scala, and the momentum behind Scala is now unquestionable. While Scala is not a dynamic language, it has many of the characteristics of popular dynamic languages, through its rich and flexible type system, its sparse and clean syntax, and its marriage of functional and object paradigms.” - Charles Nutter, creator of JRuby “I can honestly say if someone had shown me the Programming in Scala book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy.” - James Strachan, creator of Groovy Розподілені обчислення

8 Let’s see an example: Розподілені обчислення

9 A class... public class Person { public final String name; public final int age; Person(String name, int age) { this.name = name; this.age = age; } class Person(val name: String, val age: Int) {}... in Java:... in Scala: Розподілені обчислення

10... and its usage import java.util.ArrayList;... Person[] people; Person[] minors; Person[] adults; { ArrayList minorsList = new ArrayList (); ArrayList adultsList = new ArrayList (); for (int i = 0; i < people.length; i++) (people[i].age < 18 ? minorsList : adultsList).add(people[i]); minors = minorsList.toArray(people); adults = adultsList.toArray(people); }... in Java:... in Scala: val people: Array[Person] val (minors, adults) = people partition (_.age < 18) A simple pattern match An infix method call A function value Розподілені обчислення

11 But there’s more to it Розподілені обчислення

12 Embedding Domain-Specific Languages Scala’s flexible syntax makes it easy to define high-level APIs & embedded DSLs Examples: - Scala actors (the core of Twitter’s message queues) - specs, ScalaCheck - ScalaFX - ScalaQuery scalac’s plugin architecture makes it easy to typecheck DSLs and to enrich their semantics. // asynchronous message send actor ! message // message receive receive { case msgpat 1 => action 1 … case msgpat n => action n } Розподілені обчислення

13 The Essence of Scala The work on Scala was motivated by two hypotheses: Hypothesis 1: A general-purpose language needs to be scalable; the same concepts should describe small as well as large parts. Hypothesis 2: Scalability can be achieved by unifying and generalizing functional and object- oriented programming concepts Розподілені обчислення

14 Why unify FP and OOP? Both have complementary strengths for composition: Object-oriented programming: Makes it easy to adapt and extend complex systems, using subtyping and inheritance, dynamic configurations, classes as partial abstractions. Functional programming: Makes it easy to build interesting things from simple parts, using higher-order functions, algebraic types and pattern matching, parametric polymorphism Розподілені обчислення

15 Scala Scala is an object-oriented and functional language which is completely interoperable with Java. (the.NET version is currently under reconstruction.) It removes some of the more arcane constructs of these environments and adds instead: (1) a uniform object model, (2) pattern matching and higher-order functions, (3) novel ways to abstract and compose programs Розподілені обчислення

16 Scala is interoperable Scala programs interoperate seamlessly with Java class libraries: –Method calls –Field accesses –Class inheritance –Interface implementation all work as in Java. Scala programs compile to JVM bytecodes. Scala’s syntax resembles Java’s, but there are also some differences. object Example1 { def main(args: Array[String]) { val b = new StringBuilder() for (i  0 until args.length) { if (i > 0) b.append(" ") b.append(args(i).toUpperCase) } Console.println(b.toString) } object instead of static members Array[String] instead of String[] Scala’s version of the extended for loop (use <- as an alias for  ) Arrays are indexed args(i) instead of args[i] Розподілені обчислення

17 Scala is functional The last program can also be written in a completely different style: –Treat arrays as instances of general sequence abstractions. –Use higher-order functions instead of loops. object Example2 { def main(args: Array[String]) { println(args.map(_.toUpperCase).mkString(" ") } Arrays are instances of sequences with map and mkString methods. A closure which applies the toUpperCase method to its String argument map is a method of Array which applies the function on its right to each array element. mkString is a method of Array which forms a string of all elements with a given separator between them Розподілені обчислення

18 Scala is concise Scala’s syntax is lightweight and concise. Contributors: –semicolon inference, –type inference, –lightweight classes, –extensible API’s, –closures as control abstractions. Average reduction in LOC wrt Java: ≥ 2 due to concise syntax and better abstraction capabilities ***** Guy Steele: Scala led to a 4 times LOC reduction in the Fortress typechecker ***** var capital = Map( "US"  "Washington", "France"  "paris", "Japan"  "tokyo" ) capital += ( "Russia"  "Moskow" ) for ( (country, city)  capital ) capital += ( country  city.capitalize ) assert ( capital("Japan") == "Tokyo" ) Розподілені обчислення

19 Scala is precise All code on the previous slide used library abstractions, not special syntax. Advantage: Libraries are extensible and give fine- grained control. Elaborate static type system catches many errors early. import scala.collection.mutable._ val capital = new HashMap[String, String] with SynchronizedMap[String, String] { override def default(key: String) = "?" } capital += ( "US"  "Washington", "France"  "Paris", "Japan"  "Tokyo" ) assert( capital("Russia") == "?" ) Specify kind of collections: mutable Specify map implementation: HashMap Specify map type: String to String Mixin trait SynchronizedMap to make capital map thread-safe Provide a default value: "?" Розподілені обчислення

TRAITS Розподілені обчислення 20

21 Big or small? Every language design faces the tension whether it should be big or small: –Big is good: expressive, easy to use. –Small is good: elegant, easy to learn. Can a language be both big and small? Scala’s approach: concentrate on abstraction and composition capabilities instead of basic language constructs. Scala addsScala removes + a pure object system - static members + operator overloading - special treatment of primitive types + closures as control abstractions - break, continue + mixin composition with traits - special treatment of interfaces + abstract type members - wildcards + pattern matching Розподілені обчислення

22 Scala is extensible Guy Steele has formulated a benchmark for measuring language extensibility [Growing a Language, OOPSLA 98]: Can you add a type of complex numbers to the library and make it work as if it was a native number type? Similar problems: Adding type BigInt, Decimal, Intervals, Polynomials... scala> import Complex._ import Complex._ scala> val x = * i x: Complex = *i scala> val y = x * i y: Complex = *i scala> val z = y + 1 z: Complex = *i Розподілені обчислення

23 Implementing complex numbers object Complex { val i = new Complex(0, 1) implicit def double2complex(x: Double): Complex = new Complex(x, 0)... } class Complex(val re: Double, val im: Double) { def + (that: Complex): Complex = new Complex(this.re + that.re, this.im + that.im) def - (that: Complex): Complex = new Complex(this.re - that.re, this.im - that.im) def * (that: Complex): Complex = new Complex(this.re * that.re - this.im * that.im, this.re * that.im + this.im * that.re) def / (that: Complex): Complex = { val denom = that.re * that.re + that.im * that.im new Complex((this.re * that.re + this.im * that.im) / denom, (this.im * that.re - this.re * that.im) / denom) } override def toString = re+(if (im < 0) "-"+(-im) else "+"+im)+"*I"... } + is an identifier; can be used as a method name Infix operations are method calls: a + b is the same as a.+(b) Objects replace static class members Implicit conversions for mixed arithmetic Class parameters instead of fields+ explicit constructor Розподілені обчислення

24 Implicits are Poor Man’s Type Classes /** A “type class” */ class Ord[T] { def < (x: T, y: T): Boolean } /** An “instance definition” */ implicit object intOrd extends Ord[Int] { def < (x: Int, y: Int) = x < y } /** Another instance definition */ implicit def listOrd[T](implicit tOrd: Ord[T]) = new Ord { def false case (Nil, _) => true case (x :: xs, y :: ts) => x < y || x == y && xs < ys } } Розподілені обчислення

25 The Bottom Line When going from Java to Scala, expect at least a factor of 2 reduction in LOC Lines Of Code (software development).Lines Of Code (software development) But does it matter? Doesn’t Eclipse write these extra lines for me? This does matter. Eye-tracking experiments* show that for program comprehension, average time spent per word of source code is constant. So, roughly, half the code means half the time necessary to understand it. *G. Dubochet. Computer Code as a Medium for Human Communication: Are Programming Languages Improving? In 21st Annual Psychology of Programming Interest Group Conference, pages , Limerick, Ireland, Розподілені обчислення

26 Part 2: The Scala Design Розподілені обчислення

27 The Scala design Scala strives for the tightest possible integration of OOP and FP in a statically typed language. This continues to have unexpected consequences. Scala unifies –algebraic data types with class hierarchies, –functions with objects This gives a nice & rather efficient formulation of Erlang style actors Розподілені обчислення

28 ADTs are class hierarchies Many functional languages have algebraic data types and pattern matching.  Concise and canonical manipulation of data structures. Object-oriented programmers object: –ADTs are not extensible, –ADTs violate the purity of the OO data model, –Pattern matching breaks encapsulation, –and it violates representation independence! Розподілені обчислення

29 Pattern matching in Scala Here's a a set of definitions describing binary trees: And here's an inorder traversal of binary trees: This design keeps –purity: all cases are classes or objects. –extensibility: you can define more cases elsewhere. –encapsulation: only parameters of case classes are revealed. –representation independence using extractors [ECOOP 07]. abstract class Tree[T] case object Empty extends Tree[Nothing] case class Binary[T](elem: T, left: Tree[T], right: Tree[T]) extends Tree[T] def inOrder [T] ( t: Tree[T] ): List[T] = t match { case Empty => List() case Binary(e, l, r) => inOrder(l) ::: List(e) ::: inOrder(r) } The case modifier of an object or class means you can pattern match on it Розподілені обчислення

30 Extractors... are objects with unapply methods.... similar to active patterns in F# unapply is called implicitly for pattern matching object Twice { def apply(x: Int) = x*2 def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None } val x = Twice(21) x match { case Twice(y) => println(x+" is two times "+y) case _ => println("x is odd") } } Розподілені обчислення

31 Functions are objects Scala is a functional language, in the sense that every function is a value. If functions are values, and values are objects, it follows that functions themselves are objects. The function type S => T is equivalent to scala.Function1[S, T] where Function1 is defined as follows : So functions are interpreted as objects with apply methods. For example, the anonymous successor function (x: Int ) => x + 1 is expanded to trait Function1[-S, +T] { def apply(x: S): T } new Function1[Int, Int] { def apply(x: Int): Int = x + 1 } Розподілені обчислення

32 Why should I care? Since (=>) is a class, it can be subclassed. So one can specialize the concept of a function. An obvious use is for arrays, which are mutable functions over integer ranges. Another bit of syntactic sugaring lets one write: a(i) = a(i) + 2 for a.update(i, a.apply(i) + 2) class Array [T] ( length: Int ) extends (Int => T) { def length: Int =... def apply(i: Int): A =... def update(i: Int, x: A): unit =... def elements: Iterator[A] =... def exists(p: A => Boolean):Boolean =... } Розподілені обчислення

33 Partial functions Another useful abstraction are partial functions. These are functions that are defined only in some part of their domain. What's more, one can inquire with the isDefinedAt method whether a partial function is defined for a given value. Scala treats blocks of pattern matching cases as instances of partial functions. This lets one write control structures that are not easily expressible otherwise. trait PartialFunction[-A, +B] extends (A => B) { def isDefinedAt(x: A): Boolean } Розподілені обчислення

34 Example: Erlang-style actors Two principal constructs (adopted from Erlang): Send (!) is asynchronous; messages are buffered in an actor's mailbox. receive picks the first message in the mailbox which matches any of the patterns mspat i. If no pattern matches, the actor suspends. // asynchronous message send actor ! message // message receive receive { case msgpat 1 => action 1... case msgpat n => action n } A partial function of type PartialFunction[MessageType, ActionType] Розподілені обчислення

35 A simple actor case class Data(b: Array[Byte]) case class GetSum(receiver: Actor) val checkSumCalculator = actor { var sum = 0 loop { receive { case Data(bytes) => sum += hash(bytes) case GetSum(receiver) => receiver ! sum } Розподілені обчислення

36 Implementing receive Using partial functions, it is straightforward to implement receive: Here, self designates the currently executing actor, mailBox is its queue of pending messages, and extractFirst extracts first queue element matching given predicate. def receive [A] (f: PartialFunction[Message, A]): A = { self.mailBox.extractFirst(f.isDefinedAt) match { case Some(msg) => f(msg) case None => self.wait(messageSent) } Розподілені обчислення

37 Library or language? A possible objection to Scala's library-based approach is: Why define actors in a library when they exist already in purer, more optimized form in Erlang? First reason: interoperability Another reason: libraries are much easier to extend and adapt than languages. Experience: Initial versions of actors used one thread per actor  lack of speed and scalability Later versions added a non- returning `receive’ called react which makes actors event- based. This gave great improvements in scalability. New variants using delimited continuations are being explored (this ICFP) Розподілені обчислення

38 Scala cheat sheet (1): Definitions Scala method definitions: def fun(x: Int): Int = { result } def fun = result Scala variable definitions: var x: int = expression val x: String = expression Java method definition: int fun(int x) { return result } (no parameterless methods) Java variable definitions: int x = expression final String x = expression Розподілені обчислення

39 Scala cheat sheet (2): Expressions Scala method calls: obj.meth(arg) or: obj meth arg Scala choice expressions: if (cond) expr1 else expr2 expr match { case pat 1 => expr case pat n => expr n } Java method call: obj.meth(arg) (no operator overloading) Java choice expressions, stats: cond ? expr1 : expr2 // expression if (cond) return expr1; // statement else return expr2; switch (expr) { case pat 1 : return expr 1 ;... case pat n : return expr n ; } // statement only Розподілені обчислення

40 Scala cheat sheet (3): Objects and Classes Scala Class and Object class Sample(x: Int) { def instMeth(y: Int) = x + y } object Sample { def staticMeth(x: Int, y: Int) = x * y } Java Class with static class Sample { final int x; Sample(int x) { this.x = x } int instMeth(int y) { return x + y; } static int staticMeth(int x, int y) { return x * y; } } Розподілені обчислення

41 Scala cheat sheet (4): Traits Scala Trait trait T { def abstractMeth(x: String): String def concreteMeth(x: String) = x+field var field = “!” } Scala mixin composition: class C extends Super with T Java Interface interface T { String abstractMeth(String x) (no concrete methods) (no fields) } Java extension + implementation: class C extends Super implements T Розподілені обчислення

42 Part 3: Programming in Scala Розподілені обчислення

43 Scala in serious use You'll see now how Scala's constructs play together in a realistic application. Task: Write a spreadsheet Start from scratch, don't use any parts which are not in the standard libraries You'll see that this can be done in under 200 lines of code. Nevertheless it demonstrates many aspects of scalability For comparison: Java demo: 850 LOC, MS Office 30Million LOC Розподілені обчислення

44 Step 1: The main function Advantage of objects over statics: objects can inherit. Hence, can hide low-level fiddling necessary to set up a swing application. package scells import swing._ object Main extends SimpleSwingApplication { def top = new MainFrame { title = "ScalaSheet" contents += new SpreadSheet(100, 26) } Розподілені обчислення

45 Step 2: The SpreadSheet class - view class SpreadSheet(val height: Int, val width: Int) extends ScrollPane { val cellModel = new Model(height, width) import cellModel.{cells, valueChanged} val table = new Table(height, width) { rowHeight = 25 autoResizeMode = Table.AutoResizeMode.Off showGrid = true gridColor = Color(150, 150, 150) def userData(row: Int, column: Int): String = { val v = this(row, column); if (v == null) "" else v.toString } override def render(isSelected: Boolean, hasFocus: Boolean, row: Int, column: Int) = if (hasFocus) new TextField(userData(row, column)) else new Label(cells(row)(column).toString) { halign = Orientation.right } reactions += { case event.TableChanged(table, firstRow, lastRow, column) => for (row <- firstRow to lastRow) cells(row)(column).formula = FormulaParsers.parse(userData(row, column)) case ValueChanged(cell) => markUpdated(cell.row, cell.column) } for (row <- cells; cell <- row) listenTo(cell) } val rowHeader = new ComponentList(0 until height map (_.toString)) { fixedCellWidth = 30 fixedCellHeight = table.rowHeight } viewportView = table; rowHeaderView = rowHeader } Property syntax; expands to method call rowHeight_=(25) This calls in turn jtable.setRowHeight(25) Розподілені обчислення

46 Step 3: The SpreadSheet class - controller class SpreadSheet(val height: Int, val width: Int) extends ScrollPane { val cellModel = new Model(height, width) import cellModel.{cells, valueChanged} val table = new Table(height, width) { rowHeight = 25 autoResizeMode = Table.AutoResizeMode.Off showGrid = true gridColor = Color(150, 150, 150) def userData(row: Int, column: Int): String = { val v = this(row, column) if (v == null) "" else v.toString } override def render(isSelected: Boolean, hasFocus: Boolean, row: Int, column: Int) = if (hasFocus) new TextField(userData(row, column)) else new Label(cells(row)(column).toString) { halign = Orientation.right } reactions += { case event.TableChanged(table, firstRow, lastRow, column) => for (row <- firstRow to lastRow) cells(row)(column).formula = FormulaParsers.parse(userData(row, column)) case ValueChanged(cell) => markUpdated(cell.row, cell.column) } for (row <- cells; cell <- row) listenTo(cell) } val rowHeader = new ComponentList((0 until height) map (_.toString)) { fixedCellWidth = 30 fixedCellHeight = table.rowHeight } viewportView = table; owHeaderView = rowHeader } Import can be used anywhere, not just at top-level Events are objects, can pattern match on them. reactions property defines component behavior with closures Розподілені обчислення

47 Spreadsheet formulas We consider: Number text Text label =expr Formulas, consisting of B12 Cell B12:C18 Range of cells add(A7,A4) Binary operation sum(A12:A14,A16) Vararg operation (no infix operations such as X+Y ) Formula expressions can nest, as in: =sum(mul(A4, 2.0), B7:B15)) Розподілені обчислення

48 Step 4: Representing formulas internally trait Formula {} case class Coord(row: Int, column: Int) extends Formula { override def toString = ('A' + column).toChar.toString + row } case class Range(c1: Coord, c2: Coord) extends Formula { override def toString = c1.toString+":"+c2.toString } case class Number(value: Double) extends Formula { override def toString = value.toString } case class Textual(value: String) extends Formula { override def toString = value.toString } case class Application(function: String, arguments: List[Formula]) extends Formula { override def toString = function+arguments.mkString("(",", ",")") } object Empty extends Textual("") Case classes enable pattern matching B12 becomes Coord(12, 1) B0:B9 becomes Range(Coord(0, 1), Coord(9, 1) becomes Number(-12.34d) ``Sales forecast'' becomes Textual("Sales forcast") add(A7, 42) becomes Application(Coord(7, 0), Number(42)) Розподілені обчислення

49 A grammar for formulas number= -?\d+(\.\d*) ident= [A-Za-z_]\w* cell=[A-Za-Z]\d+ range= cell : cell application=ident ( expr (, expr)* ) expr=number | cell | range | application formula== expr textual=[^=].* Розподілені обчислення

50 A grammar for formulas and their parsers number= -?\d+(\.\d*) """-?\d+(\.\d*)?""".r ident= [A-Za-z_]\w* """[a-zA-Z_]\w*""".r cell=[A-Za-Z]\d+ """ [A-Za-z]\d\d*""".r range= cell : cell cell~":"~cell application=ident ident~ ( expr (, expr)* ) "("~repsep(expr, ",")~")" expr=number number | cell | range | | cell application | range | application formula== expr "="~expr textual=[^=].* """[^=].*""".r Розподілені обчислення

51 Step 5: Parsing formulas object FormulaParsers extends RegexParsers { def ident: Parser[String] = """[a-zA-Z_]\w*""".r def decimal: Parser[String] = """-?\d+(\.\d*)?""".r def cell: Parser[Coord] = """[A-Za-z]\d+""".r ^^ { s => val column = s.charAt(0) - 'A' val row = s.substring(1).toInt Coord(row, column) } def range: Parser[Range] = cell~":"~cell ^^ { case c1~":"~c2 => Range(c1, c2) } def number: Parser[Number] = decimal ^^ (s => Number(s.toDouble)) def application: Parser[Application] = ident~"("~repsep(expr, ",")~")" ^^ { case f~"("~ps~")" => Application(f, ps) } def expr: Parser[Formula] = application | range | cell | number def textual: Parser[Textual] = """[^=].*""".r ^^ Textual def formula: Parser[Formula] = number | textual | "=" ~> expr def parse(input: String): Formula = parseAll(formula, input) match { case Success(e, _) => e case f: NoSuccess => Textual("["+f.msg+"]") } This makes use of an internal DSL, much like the external Lex and Yacc Розподілені обчислення

52 Step 6: Evaluating formulas trait Evaluator { this: Model => val operations = new collection.mutable.HashMap[String, List[Double] => Double] def evaluate(e: Formula): Double = e match { case Number(v) => v case Textual(_) => 0 case Coord(row, column)=> cells(row)(column).value case Application(function, arguments) => val argvals = arguments flatMap evalList operations(function)(argvals) } private def evalList(e: Formula): List[Double] = e match { case Range(_, _) => references(e) map (_.value) case _ => List(evaluate(e)) } def references(e: Formula): List[Cell] = e match { case Coord(row, column) => List(cells(row)(column)) case Range(Coord(r1, c1), Coord(r2, c2)) => for (row <- (r1 to r2).toList; column <- c1 to c2) yield cells(row)(column) case Application(function, arguments) => arguments flatMap references case => List() } Evaluate by pattern matching on the kind of formula But how does Evaluator know about cells ? Scala's Self-type feature lets us assume the type of this in Evaluator is Model Розподілені обчислення

53 Step 7: The spreadsheet Model class class Model(val height: Int, val width: int) extends Evaluator with Arithmetic { class Cell(row: Int, column: Int) extends Publisher { private var v: Double = 0 def value: Double = v def value_=(w: Double) { if (!(v == w || v.isNaN && w.isNaN)) { v = w publish(ValueChanged(this)) } private var e: Formula = Empty def formula: Formula = e def formula_=(e: Formula) { for (c <- references(formula)) deafTo(c) this.e = e for (c <- references(formula)) listenTo(c) value = evaluate(e) } reactions += { case ValueChanged(_) => value = evaluate(formula) } case class ValueChanged(cell: Cell) extends event.Event val cells = Array.fromFunction(new Cell(_, _))(width, height) } Property definitions make interesting things happen when variables are set Розподілені обчислення

54 Lessons learned DSL's can help keep software short and clear: Parser combinators, swing components and reactions. Internal DSLs have advantages over external ones. Mixin composition + self types let you write fully re-entrant complex systems without any statics. Application complexity can be reduced by the right language constructs. To ensure you always have the right constructs, you need a language that's extensible and scalable Розподілені обчислення

55 But how long will it take me to switch? Розподілені обчислення

56 100% 200% 0% 4-6 weeks8-12 weeks Learning Curves Scala Keeps familiar environment: : IDE’s: Eclipse, IDEA, Netbeans,... Tools: JavaRebel, FindBugs, Maven,... Libraries: nio, collections, FJ,... Frameworks; Spring, OSDI, J2EE,......all work out of the box.. Alex Payne, Twitter: “Ops doesn’t know it’s not Java” Productivity Alex McGuire, EDF, who replaced majority of 300K lines Java with Scala: “Picking up Scala was really easy.” “Begin by writing Scala in Java style.” “With Scala you can mix and match withwell.” your old Java.” “You can manage risk really Розподілені обчислення

57 How to get started 100s of resources on the web. Here are three great entry points: Simply Scala artima.com Scala for Java refugees Розподілені обчислення

58 How to find out more Scala site: Six books last year Розподілені обчислення

59 Soon to come New release Scala 2.8, with –named and default parameters, annotations for high performance numerical computations, –improved IDE plugin support, –and much more. New version on.NET with Visual Studio integration Розподілені обчислення

60 Long term focus: Concurrency & Parallelism Our goal: establish Scala as the premier language for multicore programming. Actors gave us a head start. Actors as a library worked well because of Scala’s flexible syntax and strong typing. The same mechanisms can also be brought to bear in the development of other concurrency abstractions, such as: –parallel collections, –software transactional memory, –stream processing Розподілені обчислення

Introduction to Scala

What’s Scala and why should You Care? It’s language written by by Martin Odersky at EPFLIt’s language written by by Martin Odersky at EPFL (École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland Influenced by ML/Haskell, Java and other languages with better support for component softwarewith better support for component software It’s a scalable Programming language for component software with a focus is on abstraction, composition, and decomposition and not on primitivesIt’s a scalable Programming language for component software with a focus is on abstraction, composition, and decomposition and not on primitives It unifies OOP and functional programmingIt unifies OOP and functional programming It interoperates with Java and.NETIt interoperates with Java and.NET 62

63 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

Getting Started in Scala 64 scala –Runs compiled scala code –Or without arguments, as an interpreter! scalac - compiles fsc - compiles faster! (uses a background server to minimize startup time) Go to scala-lang.org for downloads/documentation Read Scala: A Scalable Language (see language.html ) language.html

Features of Scala Scala is both functional and object-oriented –every value is an object –every function is a value--including methods Scala is statically typed –includes a local type inference system: –in Java 1.5: Pair p = new Pair (1, "Scala"); new Pair (1, "Scala"); – in Scala: val p = new MyPair(1, "scala"); 65

Scala – The Interpreter Easiest way to get started with Scala is by using the Scala interpreter, which is an interactive “shell” for writing Scala expressions Simply type an expression into the interpreter and it will evaluate the expression and print the resulting value. $ scala This is an interpreter for Scala. Type in expressions to have them evaluated. Type :help for more information. scala> After you type an expression, such as 1 + 2, and hit return: scala> The interpreter will print: unnamed0: Int = 3 This line includes: an automatically assigned or user-defined name to refer to the computed value (unnamed0) a colon (:) the type of the expression and its resulting value (Int) an equals sign (=) the value resulting from evaluating the expression (3) 66

More features Supports lightweight syntax for anonymous functions, higher-order functions, nested functions, currying ML-style pattern matching Integration with XML –can write XML directly in Scala program –can convert XML DTD into Scala class definitions Support for regular expression patterns 67

Other features Allows defining new control structures without using macros, and while maintaining static typing Any function can be used as an infix or postfix operator Can define methods named +, <= or :: 68

Automatic Closure Construction Allows programmers to make their own control structures Can tag the parameters of methods with the modifier def. When method is called, the actual def parameters are not evaluated and a no-argument function is passed 69

While loop example object TargetTest1 with Application { def loopWhile(def cond: Boolean)(def body: Unit): Unit = if (cond) { body; loopWhile(cond)(body); } var i = 10; loopWhile (i > 0) { Console.println(i); i = i – 1 Note: var/val Note: var/val } 70 Define loopWhile method Use it with nice syntax

Scala class hierarchy

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 72

73 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;

74 Basic Scala Class instances val c = new IntCounter[String]; Accessing members (Look Ma no args!) println(c.size); // same as c.size() Defining functions: def foo(x : Int) { println(x == 42); } def bar(y : Int): Int = y + 42; // no braces // needed! def return42 = 42; // No parameters either!

75 Functions, Mapping, Filtering Defining lambdas – nameless functions (types sometimes needed) f is now a mapping int-> int val f = x :Int => x + 42; f is now a mapping int-> int A way to haul around stateClosures! 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 doing unix pipes?)

Classes and Objects trait Nat; object Zero extends Nat { def isZero: boolean = true; def pred: Nat = throw new Error("Zero.pred"); } class Succ(n: Nat) extends Nat { def isZero: boolean = false; def pred: Nat = n; } 76

Traits Similar to interfaces in Java They may have implementations of methods But can’t contain state Can be multiply inherited from 77

More on Traits Halfway between an interface and a class, called a trait. A class can incorporate as multiple Traits like Java interfaces but unlike interfaces they can also contain behavior, like classes. Also, like both classes and interfaces, traits can introduce new methods. Unlike either, the definition of that behavior isn't checked until the trait is actually incorporated as part of a class.

Example of traits trait Similarity { def isSimilar(x: Any): Boolean; def isNotSimilar(x: Any): Boolean = !isSimilar(x); } class Point(xc: Int, yc: Int) with Similarity { var x: Int = xc; var y: Int = yc; def isSimilar(obj: Any) = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == x; } 79

Mixin class composition Basic inheritance model is single inheritance But mixin classes allow more flexibility class Point2D(xc: Int, yc: Int) { val x = xc; val y = yc; // methods for manipulating Point2Ds } class ColoredPoint2D(u: Int, v: Int, c: String) extends Point2D(u, v) { var color = c; def setColor(newCol: String): Unit = color = newCol; } 80

Mixin class composition example class Point3D(xc: Int, yc: Int, zc: Int) extends Point2D(xc, yc) { val z = zc; // code for manipulating Point3Ds } class ColoredPoint3D(xc: Int, yc: Int, zc: Int, col: String) extends Point3D(xc, yc, zc) with ColoredPoint2D(xc, yc, col); ColoredPoint2D Point2D Point3D ColoredPoint3D ColoredPoint2D

Mixin class composition Mixin composition adds members explicitly defined in ColoredPoint2D (members that weren’t inherited) Mixing a class C into another class D is legal only as long as D’s superclass is a subclass of C’s superclass. –i.e., D must inherit at least everything that C inherited Why? 82

Mixin class composition Remember that only members explicitly defined in ColoredPoint2D are mixin inherited So, if those members refer to definitions that were inherited from Point2D, they had better exist in ColoredPoint3D –They do, since ColoredPoint3D extends Point3D which extends Point2D 83

Views Defines a coercion from one type to another Similar to conversion operators in C++/C# trait Set { def include(x: int): Set; def include(x: int): Set; def contains(x: int): boolean def contains(x: int): boolean} def view(list: List) : Set = new Set { def include(x: int): Set = x prepend xs; def include(x: int): Set = x prepend xs; def contains(x: int): boolean = def contains(x: int): boolean = !isEmpty && (list.head == x || list.tail contains x) !isEmpty && (list.head == x || list.tail contains x)} 84

Views Views are inserted automatically by the Scala compiler If e is of type T then a view is applied to e if: –expected type of e is not T (or a supertype) –a member selected from e is not a member of T Compiler uses only views in scope Suppose xs : List and view above is in scope val s: Set = xs; xs contains x val s: Set =view(xs); val s: Set = view(xs); view(xs) contains x

Compound types motivation def cloneAndReset(obj: ?): Cloneable = { val cloned = obj.clone(); obj.reset; cloned } 86 trait Resetable { def reset: Unit; } trait Cloneable { def clone(); }

Compound types In Java, the “solution” is: interface CloneableAndResetable extends Cloneable, Resetable But if the original object did not use the CloneableAndResetable interface, it won’t work Scala solution: use compound types (also called intersection types) def cloneAndReset(obj: Cloneable with Resetable): Cloneable = {... } 87

Variance annotations class Array[a] { def get(index: int): a def set(index: int, elem: a): unit; } Array[String] is not a subtype of Array[Any] If it were, we could do this: val x = new Array[String](1); val y : Array[Any] = x; y.set(0, new FooBar()); // just stored a FooBar in a String array!

Variance Annotations Covariance is ok with functional data structures trait GenList[+T] { def isEmpty: boolean; def head: T; def tail: GenList[T] } object Empty extends GenList[All] { def isEmpty: boolean = true; def head: All = throw new Error("Empty.head"); def tail: List[All] = throw new Error("Empty.tail"); } class Cons[+T](x: T, xs: GenList[T]) extends GenList[T] { def isEmpty: boolean = false; def head: T = x; def tail: GenList[T] = xs } 89

Variance Annotations Can also have contravariant type parameters –Useful for an object that can only be written to Scala checks that variance annotations are sound –covariant positions: immutable field types, method results –contravariant: method argument types –Type system ensures that covariant parameters are only used covariant positions (similar for contravariant)

Types as members abstract class AbsCell { type T; val init: T; private var value: T = init; def get: T = value; def set(x: T): unit = { value = x } } def createCell : AbsCell { new AbsCell { type T = int; val init = 1 } } Clients of createCell cannot rely on the fact that T is int, since this information is hidden from them

Resources The Scala programming language home page (see ) The Scala mailing list (see bin/doc_en?liste=scala ) bin/doc_en?liste=scala The Scala wiki (see ) A Scala plug-in for Eclipse (see lang.org/downloads/eclipse/index.html ) lang.org/downloads/eclipse/index.html A Scala plug-in for IntelliJ (see ) 92

References The Scala Programming Language as presented by Donna Malayeri (see ) The Scala Language Specification 2.7 (seehttp:// ) The busy Java developer's guide to Scala: Of traits and behaviorsUsing Scala's version of Java interfaces(see ) First Steps to Scala (in Scalazine) by Bill Venners, Martin Odersky, and Lex Spoon, May 9, 2007 (see ) 93