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