Scala taxonomy explained
from Java programmer
Radim.Pavlicek@gmail.com
Agenda
● OO Features
● Pattern matching
● Functional Programming
● Actors
● Futures
● Implicits
Data Transfer Objets
class Person {
private String firstName;
String getFirstName() {
return firstName;
}
void setFirstName(String aFirstName) {
this.firstName = aFirstName;
}
}
toString
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + ''' +
", lastName='" + lastName + ''' +
'}';
}
equals
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
if (!firstName.equals(person.firstName))
return false;
if (!lastName.equals(person.lastName))
return false;
return true
}
hashCode
@Override
public int hashCode() {
int result = firstName.hashCode();
result = 31 * result + lastName.hashCode();
return result;
}
Builder
static class Builder {
String aName = "Radim";
Builder withFirstName(String aName) {
this.name = aName; return this;
}
Person build() {
Person p = new Person; p.setName(aName);
return p;
}
Case Classes
case class Person(firstName: String =
"Bill", lastName :String = "Gates")
val me = Person(lastName = "Crosby")
● Immutable
● toString, equals, hashCode
● person.copy(lastName="Malkin")
Laziness in Java
Integer cached = null;
Integer getExpensiveComputation() {
if (null == cached) {
cached = doCount();
}
return cached;
}
Lazy Definition
lazy val count = doCount()
Imports
import scala.collection.immutable.Map
object HelloWorld {
def main(args: Array[String]) {
import scala.collection.immutable.
{Map=>MobNumbers}
val my : MobNumbers[String, String] =
MobileNumbers("radim" -> "6767982408")
Console.print( my("radim") )
}
}
Java: Singletons
public class Singleton {
private Singleton INSTANCE = null;
private Singleton() {}
public Singleton getInstance() {
if (null == INSTANCE) {
INSTANCE = new Singleton()
}
}
Objects
class CompanionObjects(val id: Long, val
description: String = "")
object CompanionObjects{
def zero = new CompanionObjects(id = 0,
description = "zero")
def apply(id:Int, description:String)= new
CompanionObjets(id,description)
def one = CompanionObjets(1, "one")
val errorMessage = "ID should be positive"
}
Pattern matching
In Java:
Switch statements with String cases have
been implemented in Java SE 7, at least 16
years after they were first requested.
Pattern matching
object Matching extends App {
val name :AnyRef= ...
name match {
case "Radim" => println("me")
case "crosby" | "sidney" => println("NHL")
case Seq("sidney", _) => println("sidney with
someone")
case Seq("sidney", _*) => println("sidney with group")
case x: Int if x < 0 => println("negative number")
case y => println("Unknown " + y)
}
}
scala.annotation.switch
(ch: @switch) match {
case 'a' if eof => println("a with oef")
case 'b' => println("b")
case 'c' => println("c")
}
Functional programming
Immutability
Java
String, BigDecimal
Scala
val immutable = 1
var mutable = 2
mutable = 3
Immutability cont.
val n = "123".reverse
val m = n.reverse
println(n, m) // 321, 123
val o = new StringBuffer("123").reverse()
val p = o.reverse()
println(o, p) // 123, 123
Higher order functions
object Collections extends App{
val c = 4 to 8
val s: IndexedSeq[String] = c map(_+"th")
s map (_.toUpperCase)
println(s) //4th, 5th, 6th, 7th, 8th
}
Parallel collection
object Parralel extends App{
def time[R](block: => R): R = {
val t0 = System.nanoTime()
val result = block // call-by-name
val t1 = System.nanoTime()
println("Elapsed time: " + (t1 - t0)/1000000 + " ms")
result
}
val c = 1 to 10000000
time { c map (_ + 1) } //4935 ms
time { c.par map (_ + 1) } //3723 ms
}
Currying
object Curry extends App{
def product(i: Int)(j: Int) = i * j
def times2 = product(2)_
def times3 = product(3)_
println(times2 (4)) //8
println(times3 (4)) //12
}
Partial functions
val sample = 1 to 10
val isEven: PartialFunction[Int, String] =
{case x if x % 2 == 0 => x+" is even"}
// the method collect can use isDefinedAt
to select which members to collect
val evenNumbers = sample collect isEven
println(evenNumbers)
Actors
Futures
import ExecutionContext.Implicits.global
object Futures extends App {
@volatile var totalA = 0
val text = Future {
Thread.sleep(1000); val a = "a" * 16
}
text onSuccess {
case txt => totalA += txt.count(_ == 'a')
}
println(totalA) // 0
Thread.sleep(1000); println(totalA) //0
Thread.sleep(1000); println(totalA) //16
}
Implicit conversions
Java:
String.valueOf(int i),
Integer.parseInt(String s)
Scala:
(1 to 4).foreach(println)
Implicit parameters
object ImplicitParam extends App{
def max[T](a: T, b: T)(implicit $ev1: Ordering[T]): T =
..
class Timeout(val milis: Int)
object Timeout {
def apply(milis: Int) = new Timeout(milis)
implicit val t: Timeout = Timeout(10)
}
def query(i: Int)(implicit t: Timeout) {
println(t.milis)
}
query(1)
To be continued...

Scala taxonomy

  • 1.
    Scala taxonomy explained fromJava programmer Radim.Pavlicek@gmail.com
  • 2.
    Agenda ● OO Features ●Pattern matching ● Functional Programming ● Actors ● Futures ● Implicits
  • 3.
    Data Transfer Objets classPerson { private String firstName; String getFirstName() { return firstName; } void setFirstName(String aFirstName) { this.firstName = aFirstName; } }
  • 4.
    toString @Override public String toString(){ return "Person{" + "firstName='" + firstName + ''' + ", lastName='" + lastName + ''' + '}'; }
  • 5.
    equals @Override public boolean equals(Objecto) { if (this == o) return true; if (!(o instanceof Person)) return false; Person person = (Person) o; if (!firstName.equals(person.firstName)) return false; if (!lastName.equals(person.lastName)) return false; return true }
  • 6.
    hashCode @Override public int hashCode(){ int result = firstName.hashCode(); result = 31 * result + lastName.hashCode(); return result; }
  • 7.
    Builder static class Builder{ String aName = "Radim"; Builder withFirstName(String aName) { this.name = aName; return this; } Person build() { Person p = new Person; p.setName(aName); return p; }
  • 8.
    Case Classes case classPerson(firstName: String = "Bill", lastName :String = "Gates") val me = Person(lastName = "Crosby") ● Immutable ● toString, equals, hashCode ● person.copy(lastName="Malkin")
  • 9.
    Laziness in Java Integercached = null; Integer getExpensiveComputation() { if (null == cached) { cached = doCount(); } return cached; }
  • 10.
    Lazy Definition lazy valcount = doCount()
  • 11.
    Imports import scala.collection.immutable.Map object HelloWorld{ def main(args: Array[String]) { import scala.collection.immutable. {Map=>MobNumbers} val my : MobNumbers[String, String] = MobileNumbers("radim" -> "6767982408") Console.print( my("radim") ) } }
  • 12.
    Java: Singletons public classSingleton { private Singleton INSTANCE = null; private Singleton() {} public Singleton getInstance() { if (null == INSTANCE) { INSTANCE = new Singleton() } }
  • 13.
    Objects class CompanionObjects(val id:Long, val description: String = "") object CompanionObjects{ def zero = new CompanionObjects(id = 0, description = "zero") def apply(id:Int, description:String)= new CompanionObjets(id,description) def one = CompanionObjets(1, "one") val errorMessage = "ID should be positive" }
  • 14.
    Pattern matching In Java: Switchstatements with String cases have been implemented in Java SE 7, at least 16 years after they were first requested.
  • 15.
    Pattern matching object Matchingextends App { val name :AnyRef= ... name match { case "Radim" => println("me") case "crosby" | "sidney" => println("NHL") case Seq("sidney", _) => println("sidney with someone") case Seq("sidney", _*) => println("sidney with group") case x: Int if x < 0 => println("negative number") case y => println("Unknown " + y) } }
  • 16.
    scala.annotation.switch (ch: @switch) match{ case 'a' if eof => println("a with oef") case 'b' => println("b") case 'c' => println("c") }
  • 17.
  • 18.
  • 19.
    Immutability cont. val n= "123".reverse val m = n.reverse println(n, m) // 321, 123 val o = new StringBuffer("123").reverse() val p = o.reverse() println(o, p) // 123, 123
  • 20.
    Higher order functions objectCollections extends App{ val c = 4 to 8 val s: IndexedSeq[String] = c map(_+"th") s map (_.toUpperCase) println(s) //4th, 5th, 6th, 7th, 8th }
  • 21.
    Parallel collection object Parralelextends App{ def time[R](block: => R): R = { val t0 = System.nanoTime() val result = block // call-by-name val t1 = System.nanoTime() println("Elapsed time: " + (t1 - t0)/1000000 + " ms") result } val c = 1 to 10000000 time { c map (_ + 1) } //4935 ms time { c.par map (_ + 1) } //3723 ms }
  • 22.
    Currying object Curry extendsApp{ def product(i: Int)(j: Int) = i * j def times2 = product(2)_ def times3 = product(3)_ println(times2 (4)) //8 println(times3 (4)) //12 }
  • 23.
    Partial functions val sample= 1 to 10 val isEven: PartialFunction[Int, String] = {case x if x % 2 == 0 => x+" is even"} // the method collect can use isDefinedAt to select which members to collect val evenNumbers = sample collect isEven println(evenNumbers)
  • 24.
  • 25.
    Futures import ExecutionContext.Implicits.global object Futuresextends App { @volatile var totalA = 0 val text = Future { Thread.sleep(1000); val a = "a" * 16 } text onSuccess { case txt => totalA += txt.count(_ == 'a') } println(totalA) // 0 Thread.sleep(1000); println(totalA) //0 Thread.sleep(1000); println(totalA) //16 }
  • 26.
  • 27.
    Implicit parameters object ImplicitParamextends App{ def max[T](a: T, b: T)(implicit $ev1: Ordering[T]): T = .. class Timeout(val milis: Int) object Timeout { def apply(milis: Int) = new Timeout(milis) implicit val t: Timeout = Timeout(10) } def query(i: Int)(implicit t: Timeout) { println(t.milis) } query(1)
  • 28.