accu 2011 introduction to scala: an object functional programming language
DESCRIPTION
Peter Pilgrim Oracle Java Champion Wednesday 13 April 2011 in Cherwell Room 11am gave a 90 minute presentation on the subject Introduction into Scala : The Object-Functional Programming Language This is a presentation that out lined the technical feel of Scala 2.8 programming language. “More and more programmers are going to need to understand functional programming at a productive level. Especially over the next 5 to 10 years” - IBM, Jason Stidd, Functional Programming Blog, 2010 The presentation covers: Classes and Companion Objects Function Objects Case classes and Pattern matching Traits, Mix-ins and Compositions Scala Collections Library Frameworks “Scala enjoys a singular advantage: performance. The language is compiled to optimised byte codes and runs as fast as native Java” Infoworld, 2010 Learn More: http://xenonique.co.uk/blog/ [email protected] http://scala-lang.org/ twitter:peter_pilgrimTRANSCRIPT
INTRODUCTION INTO SCALA THE OBJECT‐FUNCTIONAL PROGRAMMING LANGUAGE
Peter PilgrimOracle Java Champion
4/14/2011 1XeNoNiQUe.co.uk (c) 2011
4/14/2011XeNoNiQUe.co.uk (c) 2011 2
Blog: www.XeNoNiQUe.co.uk/blog/ACCU: Member since 1993Education: London South Bank UniversityLanguages: Scala, Groovy, JavaFX, JavaConferences: JavaOne, ACCU, QCon,Devoxx
4/14/2011XeNoNiQUe.co.uk (c) 2011 3
“If I were a pick a language to use today other than Java, it would be Scala”
James Gosling
http://www.adam‐bien.com/roller/abien/entry/java_net_javaone_which_programming
Headline News
“More and more programmers are going to need to understand functional programming at a productive level. Especially over the next 5 to 10 years” ‐ IBM, Jason Stidd, Functional Programming Blog, 2010
“Scala enjoys a singular advantage: performance. The language is compiled to optimised byte codes and runs as fast as native Java” Infoworld, 2010
4/14/2011XeNoNiQUe.co.uk (c) 2011 4
4/14/2011XeNoNiQUe.co.uk (c) 2011 5
Demo
Today’s Agenda
Classes and Companion ObjectsFunction ObjectsCase classes and Pattern matchingTraits, Mix‐ins and CompositionsScala CollectionsLibrary Frameworks
4/14/2011XeNoNiQUe.co.uk (c) 2011 6
4/14/2011XeNoNiQUe.co.uk (c) 2011 7
The Basics
Scalable Language
4/14/2011XeNoNiQUe.co.uk (c) 2011 8
Very Bright Future
Purely Object OrientedStatically Typed
Functional
JVM Language
Martin Odersky ‐ Language Designer
4/14/2011 9XeNoNiQUe.co.uk (c) 2011
A Brief History of Scala
Make Java Better 1996 – 2000: Pizza, GJ and javac
Make a Better Java2003 : The Scala 1.0 Experiment2005 : Scala 2.0, written in Scala2006‐2011: Industrial strength
4/14/2011 10XeNoNiQUe.co.uk (c) 2011
A Java Classpublic class Person {
public final String firstName, lastName;
public final float height;
public final int age;
public Person( String firstName,
String lastName,
float height, int age ) {
this.firstName; this.lastName = lastName;
this.height = height; this.age = age;
}
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 11
Equivalent Scala class
class Person (
val firstName: String
val lastName: String,
val height: Float,
val age: Int ) { }
4/14/2011XeNoNiQUe.co.uk (c) 2011 12
Filtering Data with Javaimport java.util.ArrayList;
Person[] people = getPeople();
Person[] tallFolk;
Person[] shortFolk;
{
ArrayList<Person> tallList = new ArrayList<Person>();
ArrayList<Person> shortList = new ArrayList<Person>();
for ( int j=0; j<people.length; ++j) {
(people[j].height < 5.0 ? shortList : tallList )
.add( people[j] );
}
shortFolk = smallList.toArray( people );
tallFolk = tallList.toArray( people );
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 13
And in Scalaval people: Array[Person] = getPeople()
// Type inference
val ( smallFolk, bigFolk ) =
people partition ( _.height < 5.0 )
4/14/2011XeNoNiQUe.co.uk (c) 2011 14
4/14/2011XeNoNiQUe.co.uk (c) 2011 15
Semicolon is optional
Valsand Vars
4/14/2011XeNoNiQUe.co.uk (c) 2011 16
VariablesTwo Types of variables:val a immutable variablevar a re‐assignable variable
val s1 = “Purple Haze” // Type inference String
var s2 = “Barcelo”
s1 = “Hotel” // Won’t compile
s2 = “Electricona” // Ok!
4/14/2011XeNoNiQUe.co.uk (c) 2011 17
Variables Type Inferencesval s3: String = “Purple Haze”
val f1: Double = 3.141596527
val fruit = List(“orange”,”apple”)
// scala.collection.immutable.List[String]
val capitals = Map(“USA”-> “Washington”,
”Wales” -> “Cardiff”, “Germany” -> “Berlin” )
// scala.collection.immutable.Map[String, String]
4/14/2011XeNoNiQUe.co.uk (c) 2011 18
Scopeval s1 = “Purple Haze”
{
val s1 = “Day Tripper”
println( s1 ) // "Day Tripper"
}
println( s1 ) // "Purple Haze"
4/14/2011XeNoNiQUe.co.uk (c) 2011 19
Scala Identifiers
Four forms of Scala identifiersAlphanumeric: A letter followed by a sequence of letters or digits
_ count as a letter (but single _ is reserved)$ is reserved for system use
Operator: One of more symbolic characters such + , *, /, ‐ , %, #, !Mixed: gamma_!Quoted: any character sequence in back‐quotes: `yield`
4/14/2011XeNoNiQUe.co.uk (c) 2011 20
Basic Scala Literals
Integer: 1, 882, ‐1Boolean: true, falseDouble: 1.0, 1d, 1e3, 1.234e‐6Long: 42LFloat: 19.73fCharacters: ‘6’, ‘@’, ‘?’, `K’String: “Hello world”
4/14/2011XeNoNiQUe.co.uk (c) 2011 21
ExpressYourself
4/14/2011XeNoNiQUe.co.uk (c) 2011 22
Expressions == Resultsval msg = “Macro Economics”
val hasA =
if ( msg contains ‘a’)
“yes”
else
“no”
println(hasA) // “yes”
4/14/2011XeNoNiQUe.co.uk (c) 2011 23
Expressions On Everythingval z1 =
try {
“play havoc”
}
finally {
“yes”
}
// z1 is “yes”
4/14/2011XeNoNiQUe.co.uk (c) 2011 24
Expressions Initialise Valsval powerSeries = {
var x = 2.0;
var sum = 1.0
for ( c <- 1 to 7 ) yield {
sum += x; x = x * x; sum
}
}
// scala.collection.immutable.IndexedSeq[Double] = Vector(3.0, 7.0, 23.0, 279.0, 65815.0, 4.295033111E9, 1.8446744078004584E19)
4/14/2011XeNoNiQUe.co.uk (c) 2011 25
How To Declare Functions
def volumePrice( price: Float, vol: Int ): Float = {
if ( vol >= 1000 )
price * 0.90
else if ( vol >= 100 )
price * 0.95
else
price
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 26
Functions Written Concisely
def max( x: Double, y: Double ): Double
= if ( x > y) x else y
def min( x: Double, y: Double ): Double
= if ( x < y) y else x
// type inference on the return type: Double
def cube( x: Double ) = x * x * x
4/14/2011XeNoNiQUe.co.uk (c) 2011 27
Procedures and The Unit Type
def sideEffect(): Unit = println(“Say hi!”)
// sayHi: ()Unit
sideEffect() // prints “Say hi!”
• Unit has a value, written as ()
• Unit roughly corresponds to void in Java
4/14/2011XeNoNiQUe.co.uk (c) 2011 28
Classes
4/14/2011XeNoNiQUe.co.uk (c) 2011 29
How To Declare Classes
class Foo
val f1 = new Foo()
val f2 = new Foo
class Bar ( val name: String )
val b1 = new Bar(“Twix”)
val b2 = new Bar(“Curly-Wurly”)
4/14/2011XeNoNiQUe.co.uk (c) 2011 30
The Primary Constructor
class Person (
val firstName: String
val lastName: String,
val height: Float,
val age: Int ) {
if ( age < 0 )
throw new Exception("age?")
if ( height <= 0.5 )
throw new Exception("height?")
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 31
Class ‐ Better Style
class Person (
val firstName: String, val lastName: String,
val height: Float, val age: Int ) {
require( age > 0, "age > 0" )
require( height >= 0.5, "height >= 0.5" )
override def toString = "%s %s %3d %5.2f (ft)".
format( firstName, lastName,
age, height )
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 32
Class ‐ Auxiliary Constructors
class Complex( real: Float, imag: Float {
def this() = this(0)
def this( r: Float ) = this ( r, 0 )
def this( r: String ) =
this ( java.lang.Float.parseFloat(r), 0 );
def this( r: String, i: String ) =
this ( java.lang.Float.parseFloat(r),
java.lang.Float.parseFloat(i) )
// ...
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 33
Built‐In Control Structures #1
var x1 = 3.0
var r1 = if ( x1 >= 0 )
"positive" else "negative"
x1 = -9.25
println( if ( x1 < 0 )
"negative" else "positive" )
4/14/2011XeNoNiQUe.co.uk (c) 2011 34
Built‐In Control Structures #2
While ... Do Do ... While
var c1 = 0
var y1 = ""
while ( c1 < 4 ) {
y1 = y1 + "#" + c1
c1 += 1
}
println(y2)
var c2 = 0
var y2 = ""
do {
y2 = y2 + "#" + c2
c2 += 1
}
while ( c2 < 4 )
println(y2)
4/14/2011XeNoNiQUe.co.uk (c) 2011 35
Scala Fixes Java Mishaps
Scala Removes Scala Innovates
Break and Continue
Static members
Primitive types
Special treatment of interfaces
Operator overloading
Function objects
Companion Objects
Case classes
User control abstractions
Mix‐ins
Pattern matching
Implicit conversions
4/14/2011XeNoNiQUe.co.uk (c) 2011 36
Infix Operators in Classes
class Complex( val re:Float, val im: Float ) {
def +( x:Complex ): Complex = {
new Complex( this.re + x.re, this.im + x.im )
}
def -( x:Complex ): Complex = {
new Complex( this.re - x.re, this.im - x.im )
}
// ...
override def toString = re +
(if (im < 0 ) "-" +(-im) else "+" +im )+"i"
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 37
Using Operator Overloading
val z1 = new Complex(3,4)
val z2 = new Complex(1,2)
val z3 = z1 + z2 // = z1.+(z2)
val z4 = z1 * z2 // = z1.*(z2)
val z5 = z1 - z2 // = z1.-(z2)
val z6 = z1 / z2 // = z1./(z2)
4/14/2011XeNoNiQUe.co.uk (c) 2011 38
Infix Operator Associativity
Normally expressions associate from LEFT to RIGHT
val x = 1 + 2 + 3 + 4
val x = ((1 + 2) + 3 ) + 4
Except for those operators that end with a colon(:)
They associate from RIGHT to LEFT
val list = 1 :: 2 :: 3 :: 4 :: Nil
val list = 1 :: ( 2 :: ( 3 :: (4 :: Nil )))
4/14/2011XeNoNiQUe.co.uk (c) 2011 39
Companion Objects• Represents a single instance of a class• Serves the analogous role of “static” in Java• Frequently defines two methods apply() and
unapply() for factories and extraction
object Complex {
val i = new Complex( 0, 1 )
def apply( re: Float, im: Float ) =
new Complex( re, im )
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 40
Comprehensions
4/14/2011XeNoNiQUe.co.uk (c) 2011 41
For‐Loop Expressions
for ( j <- 1 to 4 )
println( "Iteration "+j )
// Iteration 1 .. 4
for ( j <- 1 until 4 )
println( "Iteration "+j )
// Iteration 1 .. 3
4/14/2011XeNoNiQUe.co.uk (c) 2011 42
Looping Over Collections
val fruits = List("apple", "orange","pear",
"kiwi", "plum" )
for ( fruit <- fruits )
println( fruit )
4/14/2011XeNoNiQUe.co.uk (c) 2011 43
For‐Filter Comprehensions
for ( trade <- trades
if trade.tradeType == "FX" &&
trade.amount >= 75000 &&
trade.counterparty.toUpperCase
.startsWith("North")
)
processLayerDown( trade )
4/14/2011XeNoNiQUe.co.uk (c) 2011 44
For‐Nested‐Filter Comprehension
for ( trade <- trades
if trade.tradeType == "MM" ;
if trade.origin == "Summit";
settlement <- trade.settlements
settlement.exists( _.name == Standard )
)
settleStandard( settlement )
4/14/2011XeNoNiQUe.co.uk (c) 2011 45
4/14/2011XeNoNiQUe.co.uk (c) 2011 46
Function Objects
Function Object ‐ Long Hand
val isEven = new Function1 [ Int, Boolean ] {
def apply( k: Int ) = k % 2 == 0
}
Syntactic definition for function type that:
• Accepts an Integer parameter
• Returns a Boolean value
• Defines a method called apply to invoke the function definition.
4/14/2011XeNoNiQUe.co.uk (c) 2011 47
First‐Class Functions
val isEven: (Int => Boolean) = (k: Int) => k % 2 == 0
// The verbose short‐hand notion
Functions are values, values are objectErgo, functions are objects in Scala
4/14/2011XeNoNiQUe.co.uk (c) 2011 48
First‐Class Functions
val isEven = (k: Int ) => k % 2 == 0
// The short‐hand notion // Scala infers the function type for the LHS
4/14/2011XeNoNiQUe.co.uk (c) 2011 49
Calling Function Objects
isEven.apply(24) // true
isEven(11) // false
4/14/2011XeNoNiQUe.co.uk (c) 2011 50
Filter Out Even Numbers
val numbers = List(0,1,2,3,4,5,6,7)
// List[Int] = List(0,1,2,3,4,5,6,7)
numbers.filter( isEven )
// List[Int] = List(0,2,4,6)
Apply the function object isEven to all members of the sequence
4/14/2011XeNoNiQUe.co.uk (c) 2011 51
Filter Out Even Numbers
val numbers = List(0,1,2,3,4,5,6,7)
numbers.filter( (k: Int) => k % 2 == 0 )
// in-lined function value:
// List[Int] = List(0,2,4,6)
4/14/2011XeNoNiQUe.co.uk (c) 2011 52
Filter Out Even Numbers
val numbers = List(0,1,2,3,4,5,6,7)
numbers.filter( k => k % 2 == 0 )
// 0,2,4,6
4/14/2011XeNoNiQUe.co.uk (c) 2011 53
Filter Out Even Numbers
val numbers = List(0,1,2,3,4,5,6,7)
numbers.filter( _ % 2 == 0 )
// 0,2,4,6
4/14/2011XeNoNiQUe.co.uk (c) 2011 54
Function Object Summary
4/14/2011XeNoNiQUe.co.uk (c) 2011 55
( x: Float ) => sin(pi * x) / (pi * x )
Closures
4/14/2011XeNoNiQUe.co.uk (c) 2011 56
( x: Float ) => extra + sin(pi * x) / (pi * x )
Real World Closuresvar extra = computeFudgeFactor()
reactions += {
case e:MouseClicked =>
plotXY( -1.0, 1.0, -2.0, 2.0,
( x: Float ) =>
extra + sin(pi * x) / (pi * x ) )
}
The variable extra defined in the enclosing scope is bounded to the lexical scope of the function object.
4/14/2011XeNoNiQUe.co.uk (c) 2011 57
Closure Lexical Scope
var extra = 4
val addExtra = (x: Int) => x + extra
addExtra(2) // 6
extra = 7
addExtra(2) // 9
4/14/2011XeNoNiQUe.co.uk (c) 2011 58
Curried Functions
4/14/2011XeNoNiQUe.co.uk (c) 2011 59
( x: Float )( y: Float ) => y * cos ( sin (pi * x ) )
Functions Can Return Functions
def foo1( x: Float)(y: Float ) = x*y-2*x
def foo1( x: Float) = { (y: Float ) => x*y-2*x }
val a1 = foo1( 3 ) ( 4 ) // a1 is 6.0
val a2 = foo1( 3 )
// a2 is (Float) => Float = <function1>
val a3 = a2(4) // a3 = 6.0
4/14/2011XeNoNiQUe.co.uk (c) 2011 60
Parameterised Types
class Holder [T] ( val value: T )
val chipBox = new Holder( 555 )
val z1 = chipBox.value // 555
val fruitBox = new Holder( "apple" )
val z2 = fruitBox.value // “apple”
fruitBox.value = "orange" // re-assign error
chipBox.value = 73 // re-assign error
4/14/2011XeNoNiQUe.co.uk (c) 2011 61
Call‐By‐Value versus Call‐By‐Name
Call By Value Call By Name
Expression are evaluated before being passed as a parameter to a function
def debug( s: String ):Unit
Expressions are evaluated inside the function
Computational niceUseful for library writers to create custom control abstractions
def debug( s: => String ):Unit
4/14/2011XeNoNiQUe.co.uk (c) 2011 62
Custom Control Abstractionsdef using[ T <: { def close() }, A ]
( closable: T ) ( body: T => A ) = {
try {
body( closable )
} finally {
if ( closable != null ) {
try { closable.close() } catch {
case e: Exception => // Log this error
}
}
}
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 63
Closures As Control Abstraction
import java.io._
val file = new File( "poem.txt" )
using(
new BufferedReader(
new FileReader( file )) ) {
r => println( r.readLine() )
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 64
Pattern Matching
4/14/2011XeNoNiQUe.co.uk (c) 2011 65
Case Classes
Convenience data types for pattern matchingScala compiler creates :
Class with hashCode(), equalsTo(), copy() methodsNice toString() methodDefaults to immutable data membersCompanion object Defines apply() and unapply() (extractor) methods
4/14/2011XeNoNiQUe.co.uk (c) 2011 66
Case Classes
case class Stock( name: String, size: Int )
val st1 = Stock( "EDH", 15000 )
val st2 = Stock( “XNF", 40000 )
val nameAndValue = st2.name + “ “ +st1.value
// “EDH 15000”
val st3 = st2.copy()
val st4 = st3.copy( name = "AXA")
assert( st2 == st3 ) // true
assert( st2 != st4 ) // true
4/14/2011XeNoNiQUe.co.uk (c) 2011 67
Pattern Matching on Types
val list = List( 1967, "Legacy", '£', 51.50F )
for ( e <- list ) {
e match {
case f: Float => println("A decimal "+f )
case s: String => println("A string "+s )
case c: Char => println("A character "+c )
case _ => println("I do not know “+e )
}
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 68
Pattern Matching on Sequences
val list = List( 1967, "Legacy", '£', 51.50F )
list match {
case 1967 :: _ :: ‘£’ :: _ => println("got it")
case _ => println("not found" )
}
list match {
case List( 1967, "Legacy", _* ) => println("got two" )
case _ => println("not found")
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 69
Pattern Matching Algorithms
def fib( n: Int ): Long = {
n match {
case 0 => 0
case 1 => 1
case n => fib(n-2) + fib(n-1)
}
}
val z1 = fib(3) // 2
val series = (0 to 25).map( fib _ ).mkString("\n")
4/14/2011XeNoNiQUe.co.uk (c) 2011 70
Case Classes Abstract Data Types
abstract class BinTree[T]
case object Empty extends BinTree
case class Node (
elem: T, left: BinTree[T], right: BinTree[T]
) extends BinTree
4/14/2011XeNoNiQUe.co.uk (c) 2011 71
Pattern Matching Algorithm
// Traverse tree in-order by algorithmic cases
def inOrder[T]( n: BinTree[T] ) : List[T] = {
n match {
case Empty => List()
case BinTree(e,l,r) =>
inOrder(l) ::: List(e) ::: inOrder(r)
}
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 72
Pattern Matching Algorithm
// Recursively find the depth of the binary tree
def depth[T]( n: BinTree[T] ): Int = {
n match {
case Empty => 0
case Node( _, Empty, r ) => 1 + depth(r)
case Node( _, l, Empty ) => 1 + depth(l)
case Node( _, l, r ) =>
Math.max( depth(l), depth(r)) + 1
}
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 73
4/14/2011XeNoNiQUe.co.uk (c) 2011 74
Composition
Traits and Mix‐ins
Trait is provides composition of behaviour type in ScalaTraits can define abstract methodsTraits can define implementation methodsTraits can define data membersLinearisation of behaviour is prioritised from left to rightTraits can inherit from other traits
4/14/2011XeNoNiQUe.co.uk (c) 2011 75
Mix‐Ins and Traits
trait Vehicle
trait Car extends Vehicle
trait Bicycle extends Vehicle
trait Motorcycle extends Vehicle
trait Powered
trait HasWheels
4/14/2011XeNoNiQUe.co.uk (c) 2011 76
Mix‐In Composition
class Ford extends Car with Powered with HasWheels
class Chopper extends Bicycle with HasWheels
val myCar = new Ford
val myBike = new Chopper
4/14/2011XeNoNiQUe.co.uk (c) 2011 77
Mix‐Ins Refactored
trait Powered {
def kickdown() = "Vrroom!!"
}
trait HasWheels {
def turn() = "Wheels are turning"
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 78
Mix‐ins Refactored #2
trait Vehicle
trait Car extends Vehicle with HasWheels
with Powered
trait Bicycle extends Vehicle with HasWheels
trait Motorcycle extends Vehicle with HasWheels
with Powered
trait Bus extends Car
trait Truck extends Car
trait SUV extends Car
4/14/2011XeNoNiQUe.co.uk (c) 2011 79
Motorway Responsibility
def motorway( x: Vehicle with Powered ) =
println( "on the motorway: " +x.kickdown )
val aCar = new Ford
val aBike = new Chopper
motorway( aCar ) // Ok
motorway( aBike ) // Won’t compile!
4/14/2011XeNoNiQUe.co.uk (c) 2011 80
Collections
4/14/2011XeNoNiQUe.co.uk (c) 2011 81
Immutable Listsscala.collection.immutable.List
• Insertion at front O(1)• Insertion at end O(n)
4/14/2011XeNoNiQUe.co.uk (c) 2011 82
Creating List Collections
import scala.collection.immutable.List
val xs0 = List(1,2,3,4)
val xs1 = 1 :: 2 :: 3 :: 4 :: Nil
4/14/2011XeNoNiQUe.co.uk (c) 2011 83
Creating Nested Lists
val xs2 = ( 1 :: 2 :: 3 :: Nil) ::
( 4 :: 5 :: Nil ) ::
( 6 :: Nil ) ::
Nil
// xs2: List[List[Int]] =
List(List(1, 2, 3), List(4, 5), List(6))
4/14/2011XeNoNiQUe.co.uk (c) 2011 84
List Functions
val list = List(1,2,3,4,5)
val z0 = list.head // 1
val z1 = list.tail // List(2,3,4)
val z2 = list.isEmpty // false
val z3 = list.size // 4
4/14/2011XeNoNiQUe.co.uk (c) 2011 85
Higher Order Operations
val list = List(1,2,3,4,5)
val z0 = list.last // Int 5
val z1 = list.map( _ + 3 ) // List( 4,5,6,7,8 )
val z2 = list.take( 2 ) // List(1,2)
val z3 = list.drop( 2 ) // List(3,4,5)
val z4 = list.slice( 2,4 ) // List(3,4)
val z5 = list.reverse // List(5,4,3,2,1)
val z7 = list.contains(3) // true
val z8 = list.filter( _ < 3 ) // List( 1,2 )
4/14/2011XeNoNiQUe.co.uk (c) 2011 86
Sorting List Collections
val xs = List( 11, 7, 2, 15, 9, 1 )
val x0 = xs.sort( _ < _ )
// List[Int](1, 2, 7, 9, 11, 15)
val x1 = xs.sort( _ > _ )
// List[Int](15, 11, 9, 7, 2, 1)
4/14/2011XeNoNiQUe.co.uk (c) 2011 87
More Higher Operations
val xs = List( "apple", “plum", "orange" )
val z0 = xs.zipWithIndex
// List((apple,0), (plum,1), (orange,2))
val ys = List( "usa", "uk", "france" )
val z1 = xs zip ys
// List((apple,usa), (plum,uk), (orange,france))
val zs = List( List(1,2,3), List(4,5), List(6))
val z2 = zs flatten
// List(1, 2, 3, 4, 5, 6)
4/14/2011XeNoNiQUe.co.uk (c) 2011 88
Map Collections Types
var capitals = Map( "England" -> "London",
"Scotland" -> "Edinburgh", "Wales" -> "Cardiff", "Northern Ireland" -> "Belfast" )
capitals += ( "Brasil" -> "Brasilia" )
val z0 = capitals( "Brasil“ ) // “Brasilia”
val z1 = capitals.isEmpty // false
val z2 = capitals.size // 4
for ( (k,v) <- capitals )
println("Capital of "+k+" is "+v )
4/14/2011XeNoNiQUe.co.uk (c) 2011 89
Set Collections Types
import scala.collection.immutable.SortedSet
var xs = SortedSet( 3,2,1 )
println(xs) // TreeSet(1,2,3 )
xs += 4
xs += 3
println(xs) // TreeSet(1,2,3,4 )
xs -= 2
println(xs) // TreeSet(1,3,4 )
xs ++= List( 5,6)
println(xs) // TreeSet(1,2,4,5,6 )
4/14/2011XeNoNiQUe.co.uk (c) 2011 90
Implicit Conversions
“Can you make an ADT from a library and make it look just like it is part of the language?”,Guy Steele, Benchmark of Languages
Implicit informs the compiler about a custom default conversion methodPower enabler for writing embedded DSL in Scala
4/14/2011XeNoNiQUe.co.uk (c) 2011 91
Declare Implicit Conversions
object Complex {
implicit def doubleToComplex( x: Double ) =
new Complex( x, 0 )
val i = new Complex( 0, 1 )
def apply( re: Float, im: Float ) =
new Complex( re, im )
}
4/14/2011XeNoNiQUe.co.uk (c) 2011 92
Using Implicit Conversion
import xenonique.numerics.Complex
val z1 = new Complex( 4.7, -2.3 )
val z4 = 2 + c1
val z2 = 2.50 * c1
val z3 = (2.50).*(c1)
4/14/2011XeNoNiQUe.co.uk (c) 2011 93
Tools
4/14/2011XeNoNiQUe.co.uk (c) 2011 94
Builders
Scala – Launcher / REPLScalac ‐CompilerScaladoc – Documentation GeneratorSBT ‐ Simple Build Tool Maven Scala Plug‐inApache Ant Plug‐InGradle
4/14/2011XeNoNiQUe.co.uk (c) 2011 95
Tools ‐ IDEs
Intellij IDEA v10.2Eclipse Helios v3.6Net Beans v7.0EmacsJEdit, NotePad++, TextPad, TextMate
4/14/2011XeNoNiQUe.co.uk (c) 2011 96
Tools ‐ Frameworks
Testing Domain Specific
Scala Test SpecsScala Check
Lift AkkaPlay!Camel DSLWicket
Squeryl, Pinky, Sweet
4/14/2011XeNoNiQUe.co.uk (c) 2011 97
End Game4/14/2011XeNoNiQUe.co.uk (c) 2011 98
Breaking The Mono‐Culture
4/14/2011XeNoNiQUe.co.uk (c) 2011 99
“Do not throw the baby out with the bath water by clinging to a Java‐only monoculture approach: it matters not that what current systems are written in, when running on the JVM, only what happens in the future”
Dr. Russel Winder, Consultant
http://groups.google.com/group/javaposseThread: “Your Experience of Alternative JVM Languages in Organisations, Divisions and Teams”
Beyond Java Today
4/14/2011 100XeNoNiQUe.co.uk (c) 2011
Beyond Java Future 2016?
4/14/2011 101XeNoNiQUe.co.uk (c) 2011
Scalable Language
4/14/2011XeNoNiQUe.co.uk (c) 2011 102
Powerful
Deep LanguageResponsible
Comprehensive
Expressive Concise
Learn more
4/14/2011XeNoNiQUe.co.uk (c) 2011 103
http://xenonique.co.uk/blog/[email protected]://scala‐lang.org/twitter:peter_pilgrim
Professional Services
4/14/2011XeNoNiQUe.co.uk (c) 2011 104
[email protected] Adoption in EnterprisesContractingTraining with ConsultancyTechnical Leadership
Introduction to ScalaThe Object‐Functional Programming Language
Peter PilgrimJava Champion ‐Java EE specialist w/ ScalaenthusiasmXeNoNiQUe.co.uk/blog
4/14/2011XeNoNiQUe.co.uk (c) 2011 105
Recommended References
Programming in Scala by Martin Odersky, Lex Spoon, Bill Venners ; Artima; 2nd Edition 2010 http://www.artima.com/shop/programming_in_scala
Programming Scala by Wampler, Payne; O’Reilly; 2010; http://programming‐scala.labs.oreilly.com/
Beginning Scala by David Pollak; Apress; 2009; http://www.apress.com/book/view/1430219890
Steps in Scala by Loverdos , Syropoulos; Cambridge Univ Press; 2010;
4/14/2011XeNoNiQUe.co.uk (c) 2011 106
Popular Scala Frameworks
Scala Test http://www.scalatest.org/
Scala Check https://www.ohloh.net/p/scalacheck
Lift http://www.liftweb.net/
Akka http://akka.io/
Play! Scala module http://www.playframework.org/modules/scala
Camel DSL http://camel.apache.org/scala‐dsl.html
Squeryl http://squeryl.org/
Pinky https://github.com/pk11/pinky/wiki
Sweet [Scala] http://code.google.com/p/sweetscala/
4/14/2011XeNoNiQUe.co.uk (c) 2011 107
Attributions
All images are Creative Commons (CC) License from Flickr.com– “You must attribute the source and you cannot change the content”
Tim Ellis http://www.flickr.com/photos/tim_ellis/
Lego Basics http://www.flickr.com/photos/tim_ellis/338755101/sizes/l/
*PaysImaginaire* http://www.flickr.com/photos/nevrlndtink/
Variable Plastic Bag http://www.flickr.com/photos/nevrlndtink/232906118/sizes/m/
~Deiby http://www.flickr.com/photos/deiby/
Expression http://www.flickr.com/photos/deiby/5489382677/sizes/l/
Lisa Sinclair http://www.flickr.com/photos/plumandjello/
fruit http://www.flickr.com/photos/plumandjello/2333263539/sizes/l/
Nerovivo http://www.flickr.com/photos/dominik99/
http://www.flickr.com/photos/dominik99/407716865/sizes/z/in/photostream/
4/14/2011XeNoNiQUe.co.uk (c) 2011 108
Attributions
All images are Creative Commons (CC) License from Flickr.com
– “You must attribute the source and you cannot change the content”
.Guilty http://www.flickr.com/photos/roll_initiative/
Arbitrary Function Generator http://www.flickr.com/photos/roll_initiative/3278642272/
Loop Oh Rupert Grazer http://www.flickr.com/photos/loop_oh/
Pattern at the Senckenberg Museum in Frankfurt am Main / Germany. http://www.flickr.com/photos/loop_oh/4571485915/
Lili Vieira de Carvalho, Vancouver, Canada http://www.flickr.com/people/lilivc/
Composition of Bowls http://www.flickr.com/photos/lilivc/367582911/sizes/l/
Mykl Roventine http://www.flickr.com/people/myklroventine/
19/365 Game Over http://www.flickr.com/photos/myklroventine/3210068573/sizes/l/
superciliousness / Bentley Smith http://www.flickr.com/people/superciliousness/
200510 carpenter's tools ‐ inside the workman's shed ‐ all his old tools http://www.flickr.com/photos/superciliousness/57486288/
4/14/2011XeNoNiQUe.co.uk (c) 2011 109