If I were to pick a language to use on the JVM today other than Java, it would be Scala. – James Gosling, creator of Java http://www.adam-bien.com/roller/abien/entry/java_net_javaone_which_programming 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. – Charlies Nutter, JRuby lead http://blog.headius.com/2009/04/future-part-one.html My tip though for the long term replacement of javac is Scala. I'm very impressed with it! I can honestly say if someone had shown me the Programming in Scala book […] back in 2003 I'd probably have never created Groovy. – James Strachan, creator of Groovy http://macstrac.blogspot.com/2009/04/scala-as-long-term-replacement-for.html
Agenda
Background and motivation
Intro to Scala
Basic syntax
Pattern matching
Functions
Classes and traits
<break />
Practical Scala
About us
Alf Kristian Støyle and Fredrik Vraalsen
Java developers with 6 and 9 years experience
Scala enthusiasts since 2008
Developed SubmitIT for JavaZone
Alf worked on Scala application for Kommuneforlaget
Held 4 Scala training courses for 60+ participants
public class Person { private int age ; private String name ; public Person( int age, String name) { this . age = age; this . name = name; } public int getAge() { return this . age ; } public void setAge( int age) { this . age = age; } public String getName() { return this . name ; } public void setName(String name) { this . name = name; } } class Person ( var age : Int , var name : String )
List<Person> persons = ... List<Person> adults = new LinkedList<Person>(); List<Person> kids = new LinkedList<Person>(); for (Person person : persons) { if (person.getAge() < 18) { kids.add(person); } else { adults.add(person); } } val persons : List [ Person ] = ... val ( kids , adults ) = persons . partition (_. age < 18)
using ( new BufferedReader ( new FileReader ( "f.txt" ))) { reader => println ( reader . readLine() ) } BufferedReader reader = null ; try { reader = new BufferedReader( new FileReader( "f.txt" )); System. out .println(reader.readLine()); } finally { if (reader != null ) { try { reader.close(); } catch (IOException e) { // Exception on close, ignore } } }
Scala
Object oriented and functional
Statically typed
Java compatible
Compiles to Java bytecode
Existing libraries/frameworks
Better Java
;
public class Person { private int age ; private String name ; public Person( int age, String name) { this . age = age; this . name = name; } public int getAge() { return this . age ; } public void setAge( int age) { this . age = age; } public String getName() { return this . name ; } public void setName(String name) { this . name = name; } }
public class Person { private int age private String name public Person( int age, String name) { this . age = age this . name = name } public int getAge() { return this . age } public void setAge( int age) { this . age = age } public String getName() { return this . name } public void setName(String name) { this . name = name } }
Variables var i : Int = 42
Variables var i = 42 i = 3 i = "Hello world!" // compile error
Values val i = 42 i = 3 // compile error
Methods def sum ( a : Int , b : Int ): Int = { return a + b }
Methods def sum ( a : Int , b : Int ): Int = { a + b }
Methods def sum ( a : Int , b : Int ) = { a + b }
Methods def sum ( a : Int , b : Int ) = a + b
Methods def sayHello ( name : String ) { println ( "Hello, " + name ) }
Collections val list = List ( "apple" , "orange" , "banana" ) val map = Map (1 -> "one" , 2 -> "two" ) val array = Array (1, 2, 3, 4, 5) list (1) // orange map (2) // two array (3) // 4
myObject match { case 1 => println ( "First" ) case 2 => println ( "Second" ) case _ => println ( "Unknown" ) } Pattern matching
myObject match { case i : Int => println ( "Found number " + i ) case s : String => println ( "Found text " + s ) case _ => println ( "Unknown" ) } Pattern matching
val email = """ (.+) @ (.+) """ . r " scala @ java.no " match { case email ( name , domain ) => println ( "User " + name + " at " + domain ) case x => println ( x + " is not an email" ) } Pattern matching
val numbers = List (1, 2, 3) val secondNumber = numbers match { case List (_, i , _*) => Some ( i ) case _ => None } => secondNumber : Option [ Int ] = Some (2) Pattern matching
Functions Predicate <Integer> even = new Predicate <Integer>() { @ Override public boolean apply(Integer i) { return i % 2 == 0; } }; List<Integer> numbers = … // 1, 2, 3, 4 Iterable<Integer> evenNums = Iterables .filter(numbers, even); => [2, 4] Google collections:
Functions val even = ( i : Int ) => i % 2 == 0 val numbers = List (1, 2, 3, 4) val evenNums = numbers . filter ( even ) => List(2, 4) Scala collections:
Functions val numbers = List (1, 2, 3, 4) val evenNums = numbers . filter (( i : Int ) => i % 2 == 0) => List(2, 4) Scala collections:
Functions val numbers = List (1, 2, 3, 4) val evenNums = numbers . filter ( i => i % 2 == 0) => List(2, 4) Scala collections:
Functions val numbers = List (1, 2, 3, 4) val evenNums = numbers . filter (_ % 2 == 0) => List(2, 4) Scala collections:
Functions Predicate <Integer> even = new Predicate <Integer>() { @ Override public boolean apply(Integer i) { return i % 2 == 0; } }; val numbers = List (1, 2, 3, 4) val evenNums = numbers . filter (_ % 2 == 0) => List(2, 4) Scala collections:
Functions #boolean(int) even = #(int i)(i % 2 == 0) JDK7 lambda expressions: val even = ( i : Int ) => i % 2 == 0 Scala functions:
Control structures return values val numbers = for ( i <- 1 to 10) yield i val res = if ( cond ) x else y val res2 = try { x } catch { … y } finally { … }
Classes and constructors class Person ( val age : Int )
Classes and constructors class Person ( val age : Int ) { def this () = this (42) var name : String = _ override def toString = "My name is " + name }
Traits (= Interface + Mixin)
“Multiple inheritance done right”
Implement methods
Initialized fields
Abstract methods and fields
Does not support constructors
Call to super -> strict semantics
scala.Ordered trait trait Ordered [ A ] { def compare ( that : A ): Int def < ( that : A ): Boolean = ( this compare that ) < 0 def > ( that : A ): Boolean = ( this compare that ) > 0 def <= ( that : A ): Boolean = ( this compare that ) <= 0 def >= ( that : A ): Boolean = ( this compare that ) >= 0 }
The Ordered trait class Person ( val age : Int ) extends Ordered [ Person ] { def compare ( other : Person ) = this . age - other . age } val person1 = new Person (21) val person2 = new Person (31) person1 < person2 // true person1 <= person2 // true person1 >= person2 // false
“Dynamic mixins” class Person ( val name : String, val age : Int ) { override def toString = "My name is " + name } trait Loud { override def toString = super . toString . toUpperCase } val person = new Person ( "Fredrik" , 18) with Loud println ( person ) => MY NAME IS FREDRIK
Just scratching the surface...
Tuples
Singleton objects
Closures
For-comprehensions
Implicit conversions
Actors
Native XML data types
Parsers
Q & A
val xml = <break time="15" />
Practical Scala
The downside
Tools
ScalaTest
Java interoperability
Learning curve
Your choice
Functional programming
Implicit conversions
Higher order functions
IDE support
Netbeans - very good, but inferior in other areas
IntelliJ IDEA - very good, but slow compilation
Eclipse - bad, but very fast when working
Backward compatibility
Binary compatibility broken several times
Think twice before using a library
Tools demo
REPL - Read eval print loop
Maven
SBT - Simple Build Tool
IntelliJ IDEA
JRebel
"Complete Java projects 10-23 % faster"
Hotswap on steroids
Commercial, but free for Scala
ScalaTest demo
DSL for testing
Powerful assertions
Different test styles
JUnit
Functional tests
BDD test
The feel of Scala http://parleys.com/#id=10&st=5&sl=1
Java interoperability demo
Scala using Java
Java using Scala
Mixed projects?
Learning curve
Syntax small smack in the face
Easy to write Java-ish Scala
The language scales with your understanding
Gradually migrate to more functional style
What would you like to hear?
Functional programming
What is it all about?
Implicit conversion
Why does "gnirtS.gnal.avaj".reverse work?
Higher order functions
How does the using/resource handling example work?
“Functional programming”
First class functions
Pattern matching
Higher order functions
Functional programming
Mathematical functions have no side effects
f(x) = 2x + 3
In practice
Only immutable objects (and object graphs)
All field must be immutable
No side-effects from method calls
All methods must return something
Example scala.List
head :: tail
val list = List (1, 2) val myList = 1 :: 2 :: Nil // 0 :: 1 :: 2 :: Nil val myotherList = 0 :: myList