Scala introduction

Embed Size (px)

Citation preview

If I were to pick a language to use on the JVM today other than Java, it would be Scala.

James Gosling, creator of Javahttp://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 leadhttp://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 Groovyhttp://macstrac.blogspot.com/2009/04/scala-as-long-term-replacement-for.html

Agenda

Background and motivation

Intro to ScalaBasic syntax

Pattern matching

Functions

Classes and traits

Practical Scala

About us

Alf Kristian Style 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 persons = ... List adults = new LinkedList(); List kids = new LinkedList();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 compatibleCompiles 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)}

Methods

"apple".charAt(0)

"apple" charAt 0

1.0.+(2.0)

1.0 + 2.0

Collections

val list = List("apple", "orange", "banana")val map = Map(1 -> "one", 2 -> "two")val array = Array(1, 2, 3, 4, 5)

list(1)// orangemap(2)// twoarray(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

"[email protected]" 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 even = new Predicate() {@Overridepublic boolean apply(Integer i) {return i % 2 == 0;}};

List numbers = // 1, 2, 3, 4Iterable 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 even = new Predicate() {@Overridepublic 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:

Functions

Iterables.filter(numbers, #(int i)(i % 2 == 0))

JDK7 lambda expressions:

numbers.filter(_ % 2 == 0)

Scala functions:

Control structures return values

val numbers = for (i 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 = 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 // trueperson1 = 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 Loudprintln(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 =

Practical Scala

The downside

Tools

ScalaTest

Java interoperability

Learning curve

Your choiceFunctional 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 stylesJUnit

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 programmingWhat is it all about?

Implicit conversionWhy does "gnirtS.gnal.avaj".reverse work?

Higher order functionsHow 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 :: Nilval myotherList = 0 :: myList

scala.collection.immutable

...or scala.collection.mutable

Pick your poison!

Strive to be pure

Concurrency

Easier to avoid errors

Easier to test

We have a lot to learn

Q & A

Resources

[email protected] (http://lister.java.no/mailman/listinfo/scala)

http://scala.java.no

http://www.slideshare.net/stoyle/scala-intro

http://github.com/stoyle/javaBin-demo

[email protected], [email protected]