Scala is a powerful language for the JVM that is compatible with JDK 1.5+. It is a functional language maintained by Typesafe along with the community. Scala compiles to JVM bytecode like Java but has features like objects, traits, pattern matching and functional programming. James Gosling, the creator of Java, said that if he were to pick a language other than Java today, it would be Scala.
2. Criador da linguagem Scala
Compilador de Referência JAVA
Co-autor Java Generics
Martin Odersky
EPFL - École polytechnique fédérale de Lausanne
3. Scala – O que disse James Gosling?
"If I were to pick a language
to use today other than Java,
it would be Scala."
-- James Gosling, criador do Java
4. Scala – Visão Geral
Compatibilidade com a JVM (JDK 1.5+)
Linguagem funcional
Empresa Typesafe (www.typesafe.com) mantem
junto a comunidade a linguagem Scala.
5. Scala – Comparação de Byte Code
public class Hello { class Hello {
public String sayHello(String name){ def sayHello(name: String):String = {
return "Hello " + name; "Hello " + name
} }
} }
Código JAVA vs Scala
8. Scala – Orientada a Objetos
Cada valor é um objeto
scala> val a = 10
a: Int = 10
scala> a.
% & * + -
/ > >= >> >>>
^ asInstanceOf isInstanceOf toByte toChar
toDouble toFloat toInt toLong toShort
toString unary_+ unary_- unary_~ |
scala> a.+(10)
res0: Int = 20
scala> a + 10
res1: Int = 20
9. Scala – Orientada a Objetos
Classes
class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
}
override def toString(): String = "(" + x + ", " + y + ")";
}
scala> val p = new Point(10, 20)
p: Point = (10, 20)
scala> p
res0: Point = (10, 20)
10. Scala – Orientada a Objetos
Classes (Scala vs JAVA)
class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
}
override def toString(): String = "(" + x + ", " + y + ")";
}
public class Point {
int x;
int y;
Point(int xc, int yc){
x = xc;
y = yc;
}
public void move(int dx, int dy){
x = x + dx;
y = y + dy;
}
public String toString() {
return "(" + x + ", " + y + " )";
}
}
11. Scala – Orientada a Objetos
Traits
Utilizadas para definir tipos e métodos suportados de um
objeto
Similar as interfaces JAVA
Podem ser parcialmente implementadas
Não tem parâmetros para construtores
12. Scala – Orientada a Objetos
Traits
trait Similarity {
def isSimilar(x: Any): Boolean
def isNotSimilar(x: Any): Boolean = !isSimilar(x)
}
class Point(xc: Int, yc: Int) extends Similarity {
var x: Int = xc
var y: Int = yc
def isSimilar(obj: Any) =
obj.isInstanceOf[Point] &&
obj.asInstanceOf[Point].x == x
}
object TraitsTest extends Application {
val p1 = new Point(2, 3)
val p2 = new Point(2, 4)
val p3 = new Point(3, 3)
println(p1.isNotSimilar(p2)) // false
println(p1.isNotSimilar(p3)) // true
println(p1.isNotSimilar(2)) // true
}
13. Scala – Orientada a Objetos
“object”
Equivalente a uma Singleton class to Java
…
object TraitsTest extends Application {
val p1 = new Point(2, 3)
val p2 = new Point(2, 4)
val p3 = new Point(3, 3)
println(p1.isNotSimilar(p2)) // false
println(p1.isNotSimilar(p3)) // true
println(p1.isNotSimilar(2)) // true
}
14. Scala – Orientada a Objetos
“Companion Object”
Mesmo nome da classe
Definido no mesmo arquivo da classe
Possui acesso a todos os membros da classe
Muito utilizado como Factory
http://www.scala-lang.org/api
15. Scala – Orientada a Objetos
“Companion Object”
http://www.scala-lang.org/api
16. Scala – Orientada a Objetos
“object”
scala> val bd = BigDecimal("123.43")
bd: scala.math.BigDecimal = 123.43
scala> val bd = BigDecimal(123.43)
bd: scala.math.BigDecimal = 123.43
“apply Method”
scala> val bd = BigDecimal.apply("123.43")
bd: scala.math.BigDecimal = 123.43
scala> val bd = BigDecimal.apply(123.43)
bd: scala.math.BigDecimal = 123.43
17. “Case Class”
Scala – Orientada a Objetos
Classes Scala como qualquer outra
Exportam seus parâmetros de construtores
Método apply criado automaticamente
Permite decomposição funcional através de “pattern
matching”
18. Scala – Orientada a Objetos
“Case Class”
scala> abstract class Pessoa
defined class Pessoa
scala> case class PessoaFisica(nome: String, idade: Int) extends
Pessoa
defined class PessoaFisica
scala> case class PessoaJuricia(nome: String, tempoAbertura: Int)
extends Pessoa
defined class PessoaJuricia
toString implementado automaticamente
scala> val pf = PessoaFisica("Joao", 83)
pf: PessoaFisica = PessoaFisica(Joao,83)
scala> val pj = PessoaJuridica("The Corp", 4)
pj: PessoaJuridica = PessoaJuridica(The Corp,4)
scala> println(pf)
PessoaFisica(Joao,83)
scala> println(pj)
PessoaJuridica(The Corp,4)
19. Scala – Orientada a Objetos
“Case Class”
equals implementado automaticamente
scala> val x = PessoaFisica("Joao", 83)
x: PessoaFisica = PessoaFisica(Joao,83)
scala> val y = PessoaFisica("Joao", 83)
y: PessoaFisica = PessoaFisica(Joao,83)
scala> val z = PessoaFisica("Maria", 78)
z: PessoaFisica = PessoaFisica(Maria,78)
scala> x == y
res3: Boolean = true
scala> x == z
res4: Boolean = false
apply de case class em ação
scala> val pf = PessoaFisica("Isaias")
<console>:9: error: not enough arguments for method apply: (nome:
String, idade: Int)PessoaFisica in object PessoaFisica.
Unspecified value parameter idade.
val pf = PessoaFisica("Isaias")
20. Scala – Orientada a Objetos
“Pattern Matching”
def testPM(p: Pessoa){
p match {
case PessoaFisica(nome, idade) =>
println("Nome: " + nome)
println("Idade: " + idade)
case PessoaJuridica(nome, tempo) =>
println("Nome: " + nome)
println("Tempo: " + tempo)
case _ =>
println("Tipo Nao Esperado")
}
}
“Sealed Case Class”
scala> sealed abstract class Pessoa
defined class Pessoa
21. Scala – Linguagem Funcional
High Order Functions (Funções podem receber e
retornar funções)
Programação concorrente
Encoraja a utilização de variáveis imutáveis (var x val)
Estaticamente tipada
22. Scala – Linguagem Funcional
Fatorial
def fac(n : Int) = {
var r = 1
for (i <- 1 to n) r = r * i
r
}
scala> fac(5)
res0: Int = 120
Fatorial - Recursivo
def fac(n: Int): Int =
if (n <= 0) 1
else Não
n * fac(n – 1) Otimizado
scala> fac(5)
res0: Int = 120
23. Scala – Linguagem Funcional
@tailrec
def fac(n: Int): Int =
if (n <= 0) 1
else
n * fac(n – 1)
<console>:10: error: could not optimize @tailrec annotated method
fac: it contains a recursive call not in tail position
if (n <= 0) 1
else
n * fac(n -1)
^
Fatorial – Tail Recursive
@tailrec def factorial(accumulator: Int, number: Int) : Int = {
if(number == 1)
return accumulator
factorial(number * accumulator, number - 1)
} Otimizado
24. Scala – Linguagem Funcional
Melhorando a função
def factorial(number: Int) : Int = {
def factorialWithAccumulator(accumulator: Int, number: Int) : Int
= {
if (number == 1)
return accumulator
else
factorialWithAccumulator(accumulator * number, number - 1)
}
factorialWithAccumulator(1, number)
}
25. Scala – Linguagem Funcional
Functions
def <nome>(parametros) : <retorno>
def funcao1() {
println(“Funcao sem parametro e sem retorno”)
}
def funcao2(x: Int, y: String) {
println(“Funcao com parametro e sem retorno”)
}
def funcao3(x: Int, y: String) = {
println(“Funcao com parametros e retorno implicito”)
“retorno”
}
def funcao4(x: Int, y: String):String = {
println(“Funcao com parametros e retorno explicito”)
“retorno”
}
26. Scala – Linguagem Funcional
Funções Anônimas
scala> (x: Int) => x + 1
res0: Int => Int = <function1>
scala> res0(1)
res1: Int = 2
Funções como valores
scala> val inc = (x: Int) => x + 1
inc: Int => Int = <function1>
scala> inc(10)
res0: Int = 11
27. Scala – Linguagem Funcional
High Order Functions
scala> def soma(x:Int, y:Int):Int = {
| x+y
| }
soma: (x: Int, y: Int)Int
scala> soma(10,20)
res5: Int = 30
scala> def withLog(f:(Int, Int) => Int, x:Int, y:Int):Int = {
| println("Iniciando execucao da funcao")
| val result = f(x,y)
| println("Finalizando Execucao")
| result
| }
withLog: (f: (Int, Int) => Int, x: Int, y: Int)Int
scala> withLog(soma, 10, 20)
Iniciando execucao da funcao
Finalizando Execucao
res6: Int = 30
29. Scala – Linguagem Funcional
Implicit Parameters
scala> def addOne(implicit x:Int) = {
| x+1
| }
addOne: (implicit x: Int)Int
scala> addOne
<console>:9: error: could not find implicit value for parameter x:
Int
addOne
^
scala> implicit val x = 10
x: Int = 10
scala> addOne
res1: Int = 11
scala> addOne(35)
res2: Int = 36
30. Scala – Linguagem Funcional
Implicit Conversions
scala> class RichString(s:String)
defined class RichString
scala> implicit def string2RichString(s:String) = new RichString(s)
string2RichString: (s: String)RichString
scala> val x = "Isaias"
x: java.lang.String = Isaias
scala> def printString(r: RichString) {
| println(r)
| }
printString: (r: RichString)Unit
scala> printString(x)
$line1.$read$$iw$$iw$RichString@6fafc4c2
scala>
31. Scala – Linguagem Funcional
Mixin Class Composition
abstract class AbsIterator {
type T
def hasNext: Boolean
def next: T
}
trait RichIterator extends AbsIterator {
def foreach(f: T => Unit) { while (hasNext) f(next) }
}
class StringIterator(s: String) extends AbsIterator {
type T = Char
private var i = 0
def hasNext = i < s.length()
def next = { val ch = s charAt i; i += 1; ch }
}
object StringIteratorTest {
def main(args: Array[String]) {
class Iter extends StringIterator(args(0)) with RichIterator
val iter = new Iter
iter foreach println
}
}
35. Scala – Collections
Option
val map = Map("Hi" -> "Dan", "Hello" -> "Jane")
val result = map.get( "Hello" )
result match {
case None => println("No value found for key!")
case Some(x) => print("Found value" + x)
}
scala> map.get("NoKey")
res5: Option[java.lang.String] = None
36. Scala – Collections
Functional Combinators
“A saída de uma função será utilizada como entrada para outra
função”
scala> val numbers = List(1, 2, 3, 4)
numbers: List[Int] = List(1, 2, 3, 4)
scala> numbers.map((i:Int) => i * 2)
res0: List[Int] = List(2, 4, 6, 8)
scala> numbers.map(_ * 2)
res1: List[Int] = List(2, 4, 6, 8)
scala> numbers.foreach((i: Int) => i * 2) // Sem retorno
scala> var value = 0
value: Int = 0
scala> numbers.foreach((i: Int) => value = i*2)
scala> value
res1: Int = 28
46. Scala – Actors
Scala Actors
Abstração em processos Assíncronos
Comunicação através de envio e recepção de
mensagens
Tratamento de uma mensagem por vez
Melhor utilizado em cenários que podem ser divididos
em várias etapas
50. Scala – Ferramentas de Teste
ScalaTest (http://www.scalatest.org)
Test Driven Development (TDD)
Behaviour-Driven Development (BDD)
Funcional, integração e aceitação
import org.scalatest.FunSpec
class ExampleSpec extends FunSpec {
describe("A Stack") {
it("should pop values in last-in-first-out order") (pending)
it("should throw NoSuchElementException if an empty stack is
popped") (pending)
}
}
51. Scala – Ferramentas de Teste
specs2 (http://etorreborre.github.com/specs2/)
Testes unitários
Testes de aceitação
import org.specs2.mutable._
class HelloWorldSpec extends Specification {
"The 'Hello world' string" should {
"contain 11 characters" in {
"Hello world" must have size(11)
}
"start with 'Hello'" in {
"Hello world" must startWith("Hello")
}
"end with 'world'" in {
"Hello world" must endWith("world")
}
}
}
57. Scala – Timeline Twitter
Mais de 100 milhões de usuários ativos
250 mil Tweets por dia
3 mil tweets / segundo – Média diária
5 mil tweets / segundo – Pico
Mais de 10 mil Tweets / segundo (Super Bowl)
Poll-based
200 mil queries por segundo
Latência 1 milesegundo na média
Buscas
30 mil queries por segundo
https://github.com/twitter/finagle