A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Arthur Felipe Bruno Pimentel Carlos Junior Mateus Araujo

Apresentações semelhantes


Apresentação em tema: "Arthur Felipe Bruno Pimentel Carlos Junior Mateus Araujo"— Transcrição da apresentação:

1 Arthur Felipe Bruno Pimentel Carlos Junior Mateus Araujo
Scala Arthur Felipe Bruno Pimentel Carlos Junior Mateus Araujo

2 Roteiro Introdução e História da Linguagem Sintaxe Aplicações e futuro
Conclusão Referências

3 Introdução e História da Linguagem
O nome Scala significa “linguagem escalável” Projetada para integrar linguagem orientada a objetos e programação funcional Executado em plataforma Java Mesmo modelo de compilação como Java e C#

4 Introdução e História da Linguagem
Recursos orientados a objetos Cada valor é um objeto, onde seus comportamentos são descritos por classes Abstrações de classes Programação Funcional Definição de funções Funções de ordem superior Casamento de padrões Tipos algébricos

5 Introdução e História da Linguagem
O design começou em 2001 na École Polytechnique Fédérale de Lausanne (EPFL) por Martin Odersky Foi liberado no fim de 2003 e início de 2004 na plataforma Java Em Junho de 2004 na plataforma .NET

6 Introdução e História da Linguagem
Em 2009, Twitter mudou grande boa parte dos seus back-end do Ruby para Scala e pretende mudar o resto A Wattzon afirmou que toda a sua plataforma foi escrita em Scala

7 Por quê utilizar Scala?

8 Scala é Escalável Adequada para tarefas de qualquer tamanho
Muito pequenas (scripts) Muito grandes (frameworks)

9 Scala é Multiplataforma
Roda em vários ambientes  Java Virtual Machine (JVM)  Plataforma .NET  Java Platform, Micro Edition (Java ME)

10 Scala é Elegante Linguagem simples que une conceitos de OO e funcional
Facilita a manutenção dos programas Usa bibliotecas ao invés de outras linguagens para desenvolver módulos específicos Simplicidade de funcional + poder de Objetos

11 Sintaxe

12 Variáveis e Valores > var a = "Hello " a: java.lang.String = Hello
> a = a + "World!" a: java.lang.String = Hello World! > println(a) Hello World!

13 Variáveis e Valores > val b = "Bob Esponja"
b: java.lang.String = Bob Esponja > b += " e Patrick" error: reassignment to val  b += " e Patrick"     ^

14 Inferência de tipos > val t = 1 / 2 t: Int = 0
> val d: Double = 1 / 2 f: Double = 0.0 > val g : Double = 1.0 / 2.0 g: Double = 0.5

15 Funções > def scale = 5 //Uma função constante scale: Int
> def square(x: Double) = x * x  square: (Double)Double > square(2) unnamed0: Double = 4.0 > def sumOfSquares(x: Double, y: Double) = square(x) +  > square(y) sumOfSquares: (Double,Double)Double

16 Funções > def min (x:Int, y:Int) = { > if (x < y) x
>      else y      >   } min: (Int,Int)Int > def invert (x: Int) =  -x invert: (Int)Int > def invert (x: Int) : Int = { return -x } Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

17 Tudo é um objeto Não existem primitivas.
> 1233.hashCode res0: Int = 1233 Toda operação é uma chamada de uma função: > == 2.+(2) res4: Boolean = true > Console.println("Ronaldo!") Ronaldo! > Console println "Brilha muito no Corinthians" ...

18 Estruturas de controle
Praticamente todas as estruturas de controle são também expressões: > val x = if (0 < 1) 10 else 20  x: Int = 10 > val y = if (0 < 1) 10 //sem o else  y: Unit = ()  //Unit é o 'Null' em Scala Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

19 Estruturas de controle
Compreensões utilizando 'for' > val places = List("Olinda", "Recife", "São Paulo", "Manaus") > for (place <- places) > println(place) Olinda \n Recife \n São Paulo \n Manaus \n > val places2 =     List("Olinda", "Recife", "São Paulo", "Manaus","São Vicente") > for (place <- places2 if place.contains("São")) > println(place) São Paulo \n São Vicente \n Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

20 Estruturas de controle
Utilizando `yield` para passagem de valores:  val dogBreeds = List("Doberman", "Yorkshire Terrier",               "Dachshund", "Scottish Terrier", "Great Dane",     "Portuguese  Water Dog")  val filteredBreeds = for {      breed <- dogBreeds      if breed.contains("Terrier")      if !breed.startsWith("Yorkshire")   } yield breed  val dogBreeds = List("Doberman", "Yorkshire Terrier",               "Dachshund", "Scottish Terrier", "Great Dane",     "Portuguese  Water Dog")  val filteredBreeds = for {      breed <- dogBreeds      if breed.contains("Terrier")      if !breed.startsWith("Yorkshire")   } yield breed

21 Estruturas de controle
Utilizando ranges. > for (i <-1 to 10) println(i) 1 \n 2 \n ... Utilizando `while` > var count = 0 > while (count < 10) { >  count += 1 >  println(count) >}  Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

22 Funções como objetos Somatório:
> def sum(f: Int => Int, a: Int, b: Int): Int =  >  if (a > b) 0 else f(a) + sum(f, a + 1, b) sum: ((Int) => Int,Int,Int)Int Utilizando uma função anônima: > def sumSquares(a:Int, b:Int):Int = sum(((x:Int) => x*x),a,b) sumSquares: (Int,Int)Int > sumSquares(1,10) res1: Int = 385  def sum(f: Int => Int, a: Int, b: Int): Int =    if (a > b) 0 else f(a) + sum(f, a + 1, b)  def sumSquares(a:Int, b:Int):Int = sum(((x:Int) => x*x),a,b)  sumSquares(1,10)

23 Funções como objetos Currying:
> def filter(xs: List[Int], p: Int => Boolean): List[Int] = >   if (xs.isEmpty) xs >    else if (p(xs.head)) xs.head :: filter(xs.tail, p) >    else filter(xs.tail, p) filter: (List[Int],(Int) => Boolean)List[Int] > def modN(n: Int)(x: Int) = ((x % n) == 0) modN: (Int)(Int)Boolean > filter(List(1,2,3,4,5,6,7,8,9,0),modN(2)) List[Int] = List(2, 4, 6, 8, 0) Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

24 Exemplo: Quicksort (funcional)
 def sort(xs: Array[Int]): Array[Int] = {  if (xs.length <= 1) xs   else {    val pivot = xs(xs.length / 2)     Array.concat(       sort(xs filter (pivot >)),            xs filter (pivot ==),       sort(xs filter (pivot <)))   }  } Para testar: > sort(Array(15,3,44,457,18))

25 Exemplo: Quicksort (imperativo)
 def sort(xs: Array[Int]) {   def swap(i: Int, j: Int) {     val t = xs(i); xs(i) = xs(j); xs(j) = t   }   def particionar(l: Int, r: Int) {...}   particionar(0, xs.length - 1)  } Para testar: > sort(Array(15,3,44,457,18))

26 Exemplo: Quicksort (imperativo)
 def particionar(l: Int, r: Int) {   val pivot = xs((l + r) / 2)   var i = l; var j = r   while (i <= j) {      while (xs(i) < pivot) i += 1      while (xs(j) > pivot) j -= 1         if (i <= j) {           swap(i, j)           i += 1           j  -= 1         }       }   if (l < j) particionar(l, j)   if (j < r) particionar(i, r)   }

27 Pattern Matching > def matchTest(x: Int): String = x match {
>    case 1 => "one" >    case 2 => "two" >    case _ => "many" >  } matchTest: (Int)String >  println(matchTest(3)) many Pattern matching com vários tipos de objetos:

28 Pattern Matching > val willWork = List(1, 3, 23, 90)
> val willNotWork = List(4, 18, 52) > val empty = List() > for (l <- List(willWork, willNotWork, empty)) { >  l match { >    case List(_, 3, _, _) => println("Four elements, with the   >    2nd being '3'.") >    case List(_*) => println("Any other list with 0 or more       >    elements.") >  } >} Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

29 Listas > val l1 = List(1, 2, 3)
> val l2: List[Int] = 4 :: 5 :: 6 :: Nil > val l3 =  l1 :::  l2 l1: List[Int] = List(1, 2, 3) l2: List[Int] = List(4, 5, 6) l3: List[Int] = List(1, 2, 3, 4, 5, 6) > l3.foreach (n => println(n)) 1 \n 2 \n ... Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

30 Listas Alguns métodos para se trabalhar com listas:
val lista = "Will" :: "fill" :: "until" :: Nil lista(2) //retorna o segundo elemento da lista lista.count(s => s.length == 4) lista.drop(2) //lista sem os 2 primeiros elementos lista.exists(s => s == "until") lista.filter(s => s.length == 4) lista.map(s => s + "y") lista.isEmpty

31 Tuplas > def tupleator(x1: Any, x2: Any, x3: Any) = (x1, x2, x3)
> val t = tupleator("Hello", 1, 2.3) > println( "Print the whole tuple: " + t ) > println( "Print the first item:  " + t._1 ) > println( "Print the second item: " + t._2 ) > println( "Print the third item:  " + t._3 ) > val (t1, t2, t3) = tupleator("World", '!', 0x22) > println( t1 + " " + t2 + " " + t3 ) Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

32 Mapas > val stateCapitals = Map("PE" -> "Recife", "AL" -> "Maceió") stateCapitals: scala.collection.immutable (...) > println("Imprime os objetos dentro de Options") > println( "PE: " + stateCapitals.get("PE") ) > println( "SP: " + stateCapitals.get("SP") ) "Imprime os objetos dentro de Options" PE: Some(Recife) SP: None Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

33 Mapas > println( "Retirando o objeto da Option...")
> println( "PE: " + stateCapitals.get("PE").get ) > println( "SP: " +                                                                 > stateCapitals.get("SP").getOrElse("Oops2!") ) Retirando o objeto da Option... PE: Recife SP: Oops2! Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

34 Arrays > val names = Array("José","Maria") > names(0) = "João" > val cities = new Array[String](2) > cities(0) = "Recife" > cities(1) = "Olinda" > cities.foreach{println} Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

35 Classes e Objetos Em Scala todo valor é um objeto.
Em Scala todo valor é um objeto. Tipos e comportamentos de objetos são descritos por classes e traits. Todos os valores são instâncias de classes. Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

36 Hierarquia de Classes Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

37 Classes e Objetos Classes são templates estáticos que podem ser instanciados em vários objetos durante o tempo de execução. 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 + ")"; } Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

38 Classes e Objetos Object: classe com uma única instância(singleton).
Classes são instanciadas com a primitiva new. object Classes {       def main(args: Array[String]) {             val pt = new Point(1, 2)             val pt2 = new Point(3,4)             println(pt, pt2)       } } Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

39 Classes e Objetos Classes podem extender outras classes.
Métodos podem ser sobrescritos. class ColorPoint(u: Int, v: Int, c: String) extends Point(u, v) {      val color: String = c      def compareWith(pt: ColorPoint): Boolean =           (pt.x == x) && (pt.y == y) && (pt.color == color)      override def move(dx: Int, dy: Int): ColorPoint =            new ColorPoint(x + dy, y + dy, color) } Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

40 Classes e Objetos Adicionando algumas restrições em classes:
class Person(name: String, age: Int) {     if (age < 0) throw new IllegalArgumentException          def sayHello() { println("Hello, " + name) } }   class Adult(name: String, age: Int) {     require (age >= 18)         def sayHello() { println("Já pode tomar cana, " + name) } } Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

41 Case Classes São classes que exportam seus parâmetros de construtor.
Fornecem um mecanismo de decomposição recursiva através de pattern matching. abstract class Term case class Var(name: String) extends Term case class Fun(arg: String, body: Term) extends Term case class App(f: Term, v: Term) extends Term Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

42 Case Classes object TermTest extends Application {       def printTerm(term: Term) {             term match {               case Var(n) =>                      print(n)               case Fun(x, b) =>                      print("^" + x + ".")                     printTerm(b)               case App(f, v) =>                      Console.print("(")                     printTerm(f)                     print(" ")                     printTerm(v)                     print(")")       }   } Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

43 Traits Similares a interface em java. Permitem implementação parcial.
Permitem implementação parcial. trait Similaridade {     def eSimilar(x:Any) : Boolean     def naoSimilar(x:Any) : Boolean = !eSimilar(x) } Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

44 Traits O metodo "naoSimilar" não precisa ser implementado pelas classes que extenderem o trait Similaridade. Exemplo: class Ponto(xc: Int, yc: Int) extends Similaridade {   var x: Int = xc   var y: Int = yc   def eSimilar(obj: Any) =     obj.isInstanceOf[Ponto] &&     obj.asInstanceOf[Ponto].x == x }

45 Composição Mixin Especie de herança multipla.
Herda os métodos da superclasse + os novos métodos das classes mixins. Mixin: classe que aparece associada á palavra with na declaração de classes. Apenas trait pode ser usada como mixin.

46 Composição Mixin 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      }      

47 Generics class Pilha[T] {   var elems: List[T] = Nil   def push(x: T) { elems = x :: elems }   def top: T = elems.head   def pop() { elems = elems.tail } } ... val pilha = new Pilha[Int] Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

48 Estendendo a linguagem

49 Escalabilidade -> Extensibilidade
Exemplo: Tipos numéricos Linguagens atuais suportam int, float, double, long... Deveriam suportar também BigInt, BigDecimal, Complex... ? Existem boas razões para suportar todos eles, mas tornaria a linguagem muito complexa!  Solução: Permitir que os usuários extendam a linguagem conforme suas necessidades!  Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

50 Definindo um novo tipo de dados
class Rational(n: Int, d: Int) { private def gcd(x: Int, y: Int): Int = {...} private val g = gcd(n, d) val numer: Int = n/g val denom: Int = d/g   def + (that: Rational) = new Rational(numer * that.denom + that.numer * denom, denom * that.denom) def - (that: Rational) = new Rational(numer * that.denom - that.numer * denom, denom * that.denom) ... } class Rational(n: Int, d: Int) { private def gcd(x: Int, y: Int): Int = { if (x == 0) y else if (x < 0) gcd(x,y) else if (y < 0) gcd(x, y) else gcd(y % x, x) } private val g = gcd(n, d) val numer: Int = n/g val denom: Int = d/g def +(that: Rational) = new Rational(numer * that.denom + that.numer * denom, denom * that.denom) def -(that: Rational) = new Rational(numer * that.denom - that.numer * denom, denom * that.denom) def *(that: Rational) = new Rational(numer * that.numer, denom * that.denom) def /(that: Rational) = new Rational(numer * that.denom, denom * that.numer) override def toString():String = numer + "/" + denom }

51 Definindo novas estruturas de controle
object TargetTest1 extends Application {   def whileLoop(cond: => Boolean)(body: => Unit): Unit =     if (cond) {       body       whileLoop(cond)(body)     }   var i = 10   whileLoop (i > 0) {     println(i)     i -= 1   } } object TargetTest1 extends Application {   def whileLoop(cond: => Boolean)(body: => Unit): Unit =     if (cond) {       body       whileLoop(cond)(body)     }   var i = 10   whileLoop (i > 0) {     println(i)     i -= 1   } }

52 Definindo novas estruturas de controle
Utilizando using para controle de recursos: using (new BufferedReader(new FileReader(path))) {   f => println(f.readLine()) } Ao invés de: val f = new BufferedReader(new FileReader(path)) try {   println(f.readLine()) } finnaly {   if (f != null) f.close() } object TargetTest1 extends Application {   def whileLoop(cond: => Boolean)(body: => Unit): Unit =     if (cond) {       body       whileLoop(cond)(body)     }   var i = 10   whileLoop (i > 0) {     println(i)     i -= 1   } }

53 Definindo novas estruturas de controle
Implementação: def using[T <: {def close() } ]     (resource: T)     (block: T => Unit) {     try {     block(resource)   } finally {     if (resource != null) resource.close()   } } object TargetTest1 extends Application {   def whileLoop(cond: => Boolean)(body: => Unit): Unit =     if (cond) {       body       whileLoop(cond)(body)     }   var i = 10   whileLoop (i > 0) {     println(i)     i -= 1   } }

54 Concorrência

55 Concorrência Gerenciar concorrência não é tarefa fácil em muitas linguagens Como lidar com acesso simultâneo a memória, disco, variáveis e filas de mensagens? Como saber o comportamento do programa com 5,10,500 processos simultâneos?  Como gerenciar locks e notifiers? Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

56 Concorrência Infelizmente gerenciar concorrência em outras linguagens traz mais perguntas do que repostas. Felizmente, Scala oferece uma abordagem elegante e flexível para estes problemas.... Actors Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

57 Concorrência Actors na teoria:
São objetos que recebem mensagens e tomam ações baseados nelas.  Um Actor pode enviar a mensagem para outro ou criar um novo Actor de acordo com a mensagem recebida.  Não possuem sequência ou ordem de ações, não compartilham estado global. Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

58 Concorrência Actors na prática: Objeto que herda de scala.actors.Actor
Principais métodos: Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

59 Concorrência Actors na prática:
import scala.actors.Actor class Redford extends Actor { def act() { println("A lot of what acting is, is paying attention.") } } val robert = new Redford robert.start  Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

60 Concorrência Actors na prática:
 import scala.actors.Actor import scala.actors.Actor._ val paulNewman = actor { println("To be an actor, you have to be a child.") } Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

61 Concorrência Actors na prática: Enviando mensagem
import scala.actors.Actor import scala.actors.Actor._ val fussyActor = actor { loop { receive { case s: String => println("I got a String: " + s) case i: Int => println("I got an Int: " + i.toString) case _ => println("I have no idea what I just got.") } } } fussyActor ! "hi there" fussyActor ! 23 fussyActor ! 3.33  Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

62 Concorrência Actors na prática (MailBox):
import scala.actors.Actor import scala.actors.Actor._ val countActor = actor { loop { react { case "how many?" => { println("I've got " + mailboxSize.toString + " messages in my mailbox.") } } } } countActor ! 1 countActor ! 2 countActor ! 3 countActor ! "how many?" countActor ! "how many?" countActor ! 4 countActor ! "how many?" Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

63 Concorrência Actors na prática:
Aplicação exemplo Loja do barbeiro dorminhoco. Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

64 Aplicações e futuro Scala se encaixa no futuro multiplataforma e multilinguagem das linguagens de programação Scala é uma linguagem fácil de aprender para programadores Java-like.  Scala oferece mecanismos flefíveis para tratar concorrência e paralelismo. Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

65 Aplicações e futuro Principais aplicações: Kestrel
Substituiu o Starling (servidor de filas utilizado pelo Twitter) Agilizou o processo de entrega de mensagens no Twitter e resolveu antigos problemas de infra do Starling Lift Framework para criação de sistemas Web baseado em Scala. Parecido com JSF, JBoss Seam.  Como é baseado em Scala resolve facilmente problemas de Java e oferece um novo ponto de vista sobre construção de sistemas Web. Caso a função seja recursiva, o uso do '='  e o tipo de retorno são obrigatórios!

66 Conclusão Eficiente tanto para linguagens orientados a objetos quanto funcionais Independência de plataforma É escalável: atende à demanda dos usuários Linguagem de propósito geral com forma elegante, concisa e type-safe

67 Referências http://www.scala-lang.org/
Tutorial Scala - files/ScalaTutorial.pdf

68 Arthur Felipe Bruno Pimentel Carlos Junior Mateus Araujo
Dúvidas? Arthur Felipe Bruno Pimentel Carlos Junior Mateus Araujo


Carregar ppt "Arthur Felipe Bruno Pimentel Carlos Junior Mateus Araujo"

Apresentações semelhantes


Anúncios Google