SlideShare uma empresa Scribd logo
1 de 112
Baixar para ler offline
De onde viemos e para onde vamos?




               Daniel Capó Sobral
Quem sou eu?
 Daniel C. Sobral @ Stack Overflow
 dcsobral @ Twitter, Gmail/Gtalk, Skype, SliderShare
 Daniel Sobral @ Facebook, Speakers Deck, LinkedIn
 http://www.linkedin.com/in/danielsobral
 http://www.slideshare.net/dcsobral
 https://speakerdeck.com/u/dcsobral
 http://dcsobral.blogspot.com
O que eu sei de Scala?
 Scala gold badge @ Stack Overflow
 Pequenas contribuições para Scala:
    otimizações
    funcionalidades
    bug fixes
    documentação (nem tão pequenas)
 Participante ativo da comunidade Scala (listas de
  discussão, irc)
 Blog
IMPORTANTE!
 Scala 2.10.0 ainda não foi lançada!
    Na data em que esta apresentação foi escrita...
     (07/07/2012)


 As informações contidas nessa apresentação podem
  mudar antes do lançamento.
Sumário
 Histórico
 Futuro Imediato
    Versionamento
    Processo de Release
    Bug fixes
    Melhorias
    SIPs (Scala Improvement Process)
    Reflection
    Atores e Akka
 Futuro Distante
Scala 2.10.0
Histórico
  2003 2004 2005 2006 2007 2008 2009 2010 2011                                      2012

  • 0.8.1   • 1.0.0   • 1.4.0   • 2.0.0   • 2.3.2 • 2.7.1   • 2.7.3 • 2.8.0 • 2.9.0 • 2.9.2
  • 0.8.2   • 1.1.0             • 2.1.0   • 2.3.3 • 2.7.2   • 2.7.4 • 2.8.1 • 2.9.1
  • 0.9.0   • 1.1.0             • 2.1.1   • 2.4.0           • 2.7.5         • 2.8.2
  • 0.9.1   • 1.1.1             • 2.1.2   • 2.5.0           • 2.7.6
            • 1.2.0             • 2.1.3   • 2.5.1           • 2.7.7
            • 1.3.0             • 2.1.5   • 2.6.0
                                • 2.1.6   • 2.6.1
                                • 2.1.7
                                • 2.1.8
                                • 2.2.0
                                • 2.3.0
                                • 2.3.1
Alguns marcos importantes

                                                                                                           2011
                                                                                                           • Parallel Collections
                                                                               2010
                                                                               • Novo design de
                                                                                 Collections
                                                                               • Compatibilidade Binária
                                                     2008
                                                     • Java Generics
                                                     • Case Class Extractors


                            2007
                            • Extractors
                            • Private/protected
                              primary constructors
                            • Private[this]
                            • Placeholder
     2006                     parameters
     • Scalac escrito em    • Early Initialization
       Scala                • Abstract Type
     • Implicits              Constructors
     • Traits e             • Existential Types
       linearização         • Lazy values
     • Multilline Strings   • Structural Types
Scala 2.10.0
Explicando Versionamento
  2       .9      .1       -1

                           Bug
 Epoch   Major   Minor
                           fix
Versionamento – Scala 2.10.0
 Major release
 Binariamente incompatível
 Mudanças de linguagem
 Mudanças de biblioteca
 Novas depreciações
 Remoção de características depreciadas (deprecated)
    Classes
    Métodos
    Características da linguagem
Exemplos de Novas Depreciações
 Números octais!
  scala> 077
  <console>:1: warning: Treating numbers with a leading zero as octal is
  deprecated.
         077
         ^
  res10: Int = 63
 Double terminando em ponto
  scala> 1.
  <console>:1: warning: This lexical syntax is deprecated. From scala
  2.11, a dot will
  only be considered part of a number if it is immediately followed by
  a digit.
         1.
         ^
  res11: Double = 1.0
Exemplos de Depreciações
Removidas
 Características de linguagem
   for ( val i <- 1 to 10) println(i)

 Classe
   scala.collection.mutable.CloneableCollection

 Método
   scala.collection.immutable.Queue.+

 Pacotes
   scala.testing.SUnit
Melhoria no processo de release
 Processo cada vez mais automatizado
 Pacotes RPM, APT, Brew, etc
    Geração automática!
 Uso de Milestones para integrar ferramentas de
 terceiros
   M4 dia 12 de Junho
   M5 em breve
 Release Candidates para consolidar e eliminar bugs
Bug fixes
 Muitas correções!
 Novo código do pattern matcher!
 Priorização da correção de tickets!
 Novos warnings:
    Detectando bugs no próprio compilador!
 Mais contribuições de terceiros!
    git + pull request == FTW
 ...em adição ao processo natural de melhoria da
 linguagem.
Tickets fechados
 102    451   490    622    896    963    1118   1133   1195   1201   1247   1336
1430   1431   1432   1439   1510   1785   1799 2089 2094       2171   2196 2308
2322   2337 2388 2405       2435 2442 2460 2764         2782 2807     3047 3048
3098 3240     3272   3326   3343   3371   3392   3481   3566   3569 3628     3702
3708   3718   3755   3758   3761   3770 3798     3853 3854 3880 3898 3929
3960 3999     4018   4019 4025 4027 4063 4070 4098             4110   4124   4134
4147   4171   4172   4176   4216 4262 4270       4271   4273   4319 4326     4336
4355   4372   4391 4398     4417   4419 4425 4430       4441   4461 4467 4469
4478 4482 4490 4494         4501   4510   4512   4515   4535 4540     4541 4542
4547   4553   4561 4568     4570   4573   4574   4578   4579 4584 4592       4593
4595 4599     4601 4627 4636 4642 4647           4651 4656 4658       4661 4692
4696 4697 4709       4712   4713   4716   4717   4723   4727   4731   4737   4740
4749   4753   4757   4758   4759   4761 4764 4766 4770         4777 4780 4792
Tickets fechados
4794 4800 4802 4804 4807 4809              4811   4818   4823 4827 4828       4831
4833 4839 4842 4846          4851   4853 4857 4858 4859 4860           4861 4869
4871 4874 4875 4877 4879 4882              4891 4894 4898 4899 4909           4910
 4911   4925 4928 4929       4933   4935 4938 4954 4957 4959           4961 4963
4970 4975 4976 4979          4981 4985 4987 4989 5005 5009             5012   5018
5020    5023 5026 5029       5032   5033 5034     5037 5040     5041   5053 5054
5056 5062      5063 5066     5071   5072   5077 5078 5080       5083 5084 5085
5093 5096 5097 5099          5104   5105   5108   5117   5119   5121   5125   5127
 5135   5137   5147   5148   5152   5156   5162   5165   5167   5168   5175   5176
 5178   5189   5199   5201   5205 5206     5210   5212   5215   5223   5226   5229
5230    5239   5245 5248     5256   5259 5266     5267   5272 5284     5287   5291
5293    5295 5300     5305   5313   5317   5318   5328   5334   5336   5341   5343
5344    5352   5354   5356   5358   5359   5373   5374   5375   5377   5382   5384
Tickets fechados (442 – 02/Jul)
5387 5399 5405 5406 5407 5426 5428 5429                  5441 5444 5446       5451
5452    5453   5455   5471 5488 5489 5497 5500           5510   5514   5522   5528
5530    5532   5535   5537   5542   5543 5544     5545   5552   5553   5554   5564
 5571   5572   5577   5578 5580 5589 5590         5591   5593 5599 5608 5609
5610    5612   5614   5617   5623 5626     5627 5629     5632 5640     5641 5644
5648    5652 5654     5655 5656     5663 5666 5667       5672 5676     5677 5680
5682    5683 5688 5689 5690 5693 5696             5702   5703 5704 5706       5707
5708    5713   5715   5720   5728   5729   5735   5738   5742 5760     5761   5763
5769    5777   5779 5796     5801 5804 5805 5809         5816   5821 5829     5839
5840    5843   5845 5846     5853   5857 5862 5867 5879 5880           5881 5899
5910    5912   5914   5932   5953 5966 5967 5968         5971 5986     etc?
Melhorias
 Novas coleções
    Mutable SortedSet/SortedMap (baseadas em AVL)
    Mutable Concurrent Map (TrieMap)
    Parallel Mutable Concurrent Map (ParTrieMap)
 Performance:
    Immutable SortedSet/SortedMap
       Novo (private) RedBlackTree
       TreeIterator
   PartialFunction
     applyOrElse

   BitSet
   MurmurHash3 (coleções, xml, case classes)
Novidades
 Type Classes:
    Try (alternativa do Twitter ao Either)
    Hashing (já existe Equiv)
    IsTraversableOnce e IsTraversableLike
 Pacote scala.util.hashing
 Pools configuráveis em coleções paralelas
 @unspecialized
 to[Collection]
 ???
Novidades
   override object (-Yoverride-objects)
   Bytecode versão 49, 50 e 51 (-target:jvm-1.x-asm)
   -optimize mais rápido e eficiente
   -Dscala.timings=true revela quais são os pontos de
    demora na compilação
   SIP-18: -language:XXX, -feature
   logs variados
   macro variados
   patmat variados
   etc...
scala.util.Try
 def percentCompleted(total: Int,
                      done: Int): Int =
   Try ( done * 100 / total ) getOrElse 100
scala.util.Try
 Try {
   new FileInputStream(a)
 } rescue {
   case _: FileNotFoundException =>
     new FileInputStream(b)
 } recover {
   case _: FileNotFoundException =>
     defaultInputStream
 } andThen {
   stream =>
     in = stream.read(); Stream.close(); in
 }
scala.util.hashing.Hashing
 def hashingOf[T : Hashing](obj: T): Int =
   implicitly[Hashing[T]].hash(obj)

 // Uma função de hashing ruim para Seqs
 implicit val seqHashing =
   Hashing fromFunction ((_: Seq[_]).size)
IsTraversableOnce
IsTraversableLike
 class FilterMapImpl[A, Repr]
       (val r: GenTraversableLike[A, Repr]) {
   final def filterMap[B, That]
             (f: A => Option[B])
             (implicit cbf: CanBuildFrom[Repr, B, That])
             : That =
     r.flatMap(f(_).toSeq)
 }

 // Como escrever a conversão implícita???
IsTraversableOnce
IsTraversableLike
 Problemas em se escrever a conversão:
    Array e String não são GenTraversable
    String não possui parâmetro de elemento (A)
    Nem BitSet e outras coleções
    Inferência sobre view bounds é deficiente
IsTraversableOnce
IsTraversableLike
 class FilterMapImpl[A, Repr]
       (val r: GenTraversableLike[A, Repr]) {
   final def filterMap[B, That]
             (f: A => Option[B])
             (implicit cbf: CanBuildFrom[Repr, B, That])
             : That =
     r.flatMap(f(_).toSeq)
 }

 implicit def filterMap[Repr, A](r: Repr)
              (implicit fr: IsTraversableOnce[Repr])
              : FilterMapImpl[fr.A,Repr] =
   new FilterMapImpl(fr.conversion(r))
Pools Configuráveis em Coleções
Paralelas
import scala.collection.parallel._
val pc = mutable.ParArray(1, 2, 3)

pc.tasksupport = new ForkJoinTaskSupport(
  new scala.concurrent.ForkJoinPool(2))

pc map { _ + 1)

pc.tasksupport = new ThreadPoolTaskSupport()
Pools Configuráveis em Coleções
Paralelas – Customizando
class customTaskSupport extends TaskSupport {
  def execute[R, Tp]
      (task: Task[R, Tp]): () => R = ???

    def executeAndWaitResult[R, Tp]
        (task: Task[R, Tp]): R = ???

    def parallelismLevel: Int = ???
}
to[Collection]
scala> List(2, 1, 3).to[Seq]
res17: Seq[Int] = Vector(2, 1, 3)

scala> List(2, 1, 3).to[Vector]
res18: Vector[Int] = Vector(2, 1, 3)

scala> List(2, 1, 3).to[collection.mutable.Seq]
res19: scala.collection.mutable.Seq[Int] =
ArrayBuffer(2, 1, 3)

scala> List(2, 1, 3).to[collection.immutable.SortedSet]
res20: scala.collection.immutable.SortedSet[Int] =
TreeSet(1, 2, 3)
???
 ??? é um método do tipo Nothing que lança uma
  exceção
 Por ser do tipo Nothing, ??? pode aparecer no lugar
  de qualquer expressão
 Excelente para stubs, exercícios e apresentações!
???
trait Opt [A] { // Exercise by Tony Morris
  def fold[X](some: A => X, none: => X): X = ???
  def map[B](f: A => B): Opt[B] = ???
  def get: A = ???
  def flatMap[B](f: A => Opt[B]): Opt[B] = ???
  def mapAgain[B](f: A => B): Opt[B] = ???
  def getOrElse(e: => A): A = ???
  def filter(p: A => Boolean): Optional[A] = ???
  def exists(p: A => Boolean): Boolean = ???
  def forall(p: A => Boolean): Boolean = ???
  def foreach(f: A => Unit): Unit = ???
  def isDefined: Boolean = ???
  def orElse(o: => Opt[A]): Opt[A] = ???
  // etc
         Adaptado de Tony Morris, http://blog.tmorris.net/further-understanding-scalaoption/
???
trait Opt [A] { // Exercise by Tony Morris
  def fold[X](some: A => X, none: => X): X = ???
  def map[B](f: A => B): Opt[B] = ???
  def get: A = ???
  def flatMap[B](f: A => Opt[B]): Opt[B] = ???
  def mapAgain[B](f: A => B): Opt[B] = ???
  def getOrElse(e: => A): A = ???
  def filter(p: A => Boolean): Optional[A] = ???
  def exists(p: A => Boolean): Boolean = ???
  def forall(p: A => Boolean): Boolean = ???
  def foreach(f: A => Unit): Unit = ???
  def isDefined: Boolean = ???
  def orElse(o: => Opt[A]): Opt[A] = ???
  // etc
         Adaptado de Tony Morris, http://blog.tmorris.net/further-understanding-scalaoption/
Melhorias
 Scaladoc
    Implicits!
    Diagramas!
 API docs
ScalaDoc & Implicits
Parallel Collections Docs!
Diagramas de Classe!
Parâmetros para ScalaDoc
 -implicits
 -diagrams




 Esse slide foi exigência de Vlad Ureche ;-)
SIP – Scala Improvement Process
 SIP-11: String Interpolation
 SIP-12: Sintaxe das Estruturas de Controle
 SIP-13: Classes Implicitas
 SIP-14: Futures e Promises
 SIP-15: Value Classes
 SIP-16: Macros auto-limpantes
 SIP-17: Tipo Dynamic
 SIP-18: Modularização de funcionalidades da
  linguagem
 SIP-19: Posição de Código Fonte Implícitas
SIP – Scala Improvement Process
 SIP-11: String Interpolation (aceita!)
 SIP-12: Sintaxe das Estruturas de Controle (adiada)
 SIP-13: Classes Implicitas (aceita!)
 SIP-14: Futures e Promises (aceita!)
 SIP-15: Value Classes (aceita!)
 SIP-16: Macros auto-limpantes (adiada)
 SIP-17: Tipo Dynamic (aceita!)
 SIP-18: Modularização de funcionalidades da
  linguagem (aceita!)
 SIP-19: Posição de Código Fonte Implícitas (recusada)
SIP-11: String Interpolation
 Ausência de interpolação de strings motivo de constante
  reclamações
    Mas bem poucas linguagens suportam!
 Odersky diz que diferença entre ${x} e "+x+" é de um
  único caracter
    Mas ignora os shifts...
    Alegação de que " e + no teclado Suíco não precisa de shift
      Verdade!

 Reviravolta:
    E se interpolação de strings for mais do que interpolação de
     strings?
SIP-11: String Interpolation
def hello(name: String = "world"): String =
  "Hello, " + name + "! "

// Interpolation!
def hello(name: String = "world"): String =
  s"Hello, $name! "
SIP-11: String Interpolation
def percentCompleted(total: Int, done: Int): String =
  Try ( done * 100 / total ) map {
    percent => f"$percent%2d% completed"
  } getOrElse "100% completed"

def percentCompleted(total: Int, done: Int): String =
  Try (
    f"${ done * 100 / total }%2d% completed"
  ) getOrElse "100% completed"
SIP-11: String Interpolation:
Como funciona?
s"Hello, $name!" // traduzido para
StringContext("Hello, ", "!").s(name)


f"${ done * 100 / total }%2d% completed" // traduzido para
StringContext("", "%2d% completed").f(done * 100 / total)
SIP-11: String Interpolation
 Literais multi-linha também são aceitos
    s"""Ok!"""
 Interpolação pode ser aninhada
    s"${ s"$x" }"
 Contra-barra não é interpretada
    r"d+/$mes" // interpolador r não existe!
    StringContext("""d+/""").r(mes)
 Mas s e f interpretam as barras!
    s"Hello, $name!n" // newline normal
 Formas de alterar comportamento:
    Adição de métodos implícitos à StringContext
    Sobreposição de objeto ou método chamado StringContext
    “r” não precisa ser método!
SIP-11: String Interpolation
// Adição de interpolação via implicit
class RegexContext(sc: StringContext) {
  def r(args: Any*) = {
    sc.checkLengths(args: _*)
    val res = (args, sc.parts.tail).zipped map {
      (arg, part) => s"Q$argE$part"
    } mkString ""
    (sc.parts.head + res).r
  }
}

implicit def toRC(sc: StringContext) = new RegexContext(sc)
SIP-11: String Interpolation
// Aninhamento de interpoladores
class RegexContext(sc: StringContext) {
  def r(args: Any*) = {
    sc.checkLengths(args: _*)
    s"${sc.parts.head}${
      (args, sc.parts.tail).zipped map {
         (arg, part) => s"Q$argE$part"
      } mkString ""
    }".r
  }
}

implicit def toRC(sc: StringContext) = new RegexContext(sc)
SIP-11: String Interpolation
// Adição de interpolação via sobreposição
object StringContext(parts: String*) {
  def r(args: Any*) = {
    require(parts.length == args.length + 1)
    val res = (args, parts.tail).zipped map {
      "Q" + _ + "E" + _
    } mkString ""
    (parts.head + res).r }
}

// Possível alterar s e f!
SIP-11: String Interpolation
// apply e unapplySeq

def hello(name: String = "world"): String = i"Hello, $name!"

def who(message: String): String = message match {
  case i"Hello, $name!" => name
  case _                => “no clue"
}

who(hello("Daniel")) == "Daniel"
SIP-11: String Interpolation
// apply e unapplySeq
implicit class SI(sc: StringContext) {
  object i {
    def apply(args: Any*): String =
      sc.parts.head +
      (args,sc.parts.tail).zipped.map(_+_).mkString
    def unapplySeq(s: String): Option[Seq[String]] = {
      val partsr = sc.parts map (p => s"Q$pE")
      val r = (partsr mkString "(.*)").r
      s match { case r(xs @ _*) => Some(xs) case _ => None }
    }
  }
}
SIP-13: Classes Implícitas
 “Enrich My Library” (antigo “Pimp My Library”)
  extremamente popular
 Mas cerimonioso...
 “Extension methods” se tornando comuns em outras
  linguagens
 E com menos cerimônia!


 Solução: implicit class
SIP-13: Classes Implícitas
// Adição de interpolação via implicit class
implicit class RegexContext(sc: StringContext) {
  def r(args: Any*) = {
    sc.checkLengths(args: _*)
    val res = (args, sc.parts.tail).zipped map {
      "Q" + _ + "E" + _
    } mkString ""
    (sc.parts.head + res).r
  }
}
SIP-14: Futures and Promises
 Executar operações em paralelo, de forma não-bloqueante é
  uma necessidade comum
 Evidência: diversas bibliotecas contém implementações de
  Future
    Incluindo a biblioteca padrão de atores!
 Problema:
    Interface não-padronizada
    Dependência de implementação
 Solução:
    API poderosa e flexível implementando os conceitos de
     Future e Promise
SIP-14: Futures and Promises
// TODO – Desculpem! Exemplos da SIP:

import scala.concurrent._
val f: Future[List[String]] = future {
  session.getRecentPosts
}
f onComplete {
  case Right(posts) => for (post <- posts) render(post)
  case Left(t) => render("An error has occured: " +
t.getMessage)
}
SIP-14: Futures and Promises
// TODO – Desculpem! Exemplos da SIP:

import scala.concurrent._
val f: Future[List[String]] = future {
  session.getRecentPosts
}
f onFailure {
  case t => render("An error has occured: " + t.getMessage)
} onSuccess {
  case posts => for (post <- posts) render(post)
}
SIP-14: Futures and Promises
// TODO – Desculpem! Exemplos da SIP:

import scala.concurrent._
def main(args: Array[String]) {
  val rateQuote = future {
    connection.getCurrentValue(USD)
  }

  val purchase = rateQuote map {
    quote => if (isProfitable(quote)) connection.buy(amount,
quote)
             else throw new Exception("not profitable")
  }

    blocking(purchase, 0 ns)
}
SIP-14: Futures and Promises
// TODO – Desculpem! Exemplos da SIP:

import scala.concurrent.{ future, promise }
val p = promise[T]
val f = p.future
val producer = future {
  val r = produceSomething()
  p success r
  continueDoingSomethingUnrelated()
}
val consumer = future {
  startDoingSomething()
  f onSuccess {
    case r => doSomethingWithResult()
  }
}
SIP-15: Value Classes
 A maldição das referências
 A maldição do boxing:
    case class Meter(n: Int) muito mais “caro” que
     int
 A maldição do das classes implícitas:
    "abc“.r cria um objeto desnecessário só para chamar new
     Regex("abc")
 Queremos uma classe que não seja referência!
 Solução: value classes.
SIP-15: Value Classes
// Adição de interpolação via implicit value class
implicit class RegexContext(sc: StringContext) extends AnyVal {
  def r(args: Any*) = {
    sc.checkLengths(args: _*)
    val res = (args, sc.parts.tail).zipped map {
      "Q" + _ + "E" + _
    } mkString ""
    (sc.parts.head + res).r
  }
}
SIP-15: Value Classes
 Só podem ter um parâmetro
    O parâmetro deve ser um val
 Ou seja, [T: Ordering](v: T) não é aceito
 Pode ser estendidas por traits
    Se os mesmos estenderem Any ou AnyVal
 Não podem definir igualdade ou hash code
    Podem ser case classes!
 Igualdade e hash code são aplicadas sobre o parâmetro
 São efetivamente “final”
 Em um escopo local, são removidas por otimização
 Se escapam do escopo, são boxed
SIP-16: Macros
 Compiladores grandes são de difícil manutenção
    Pressão contra adição de funcionalidades
 Plugins do compilador resolvem...
    ...mas são difíceis de manter em sincronia
 Possível solução: Macros
    “Macros? Ugh!” – trauma do C/C++!
 Novidade: scala.reflection
    Macros saem quase de graça!
SIP-16: Macros
 Scala CATs!
    Compile-time AST Transformations
       Abstract Syntax Tree
 Inspirado pelas macros de Nemerle
 Quatro tipos cogitados:
   Typed macros – Somente este tipo está disponível!
   Untyped macros
   Type (class/trait) macros
   Annotation macros
SIP-16: Macros
// Typed macros

(1 to 5).foreach(println)
         ^       ^
         |       + Verificação de tipos
         + Macro executada
         + Nova verificação de tipos
SIP-16: Macros
// Untyped macros

for {val i = 0; i < 10; i += 1} println(i)
^   ^
|   |
|   + Tipo dos argumentos não é checado!
+ Macro executada
+ Verificação de tipos
SIP-16: Macros
// Untyped macros – porque?

for {val i = 0; i < 10; i += 1} println(i)
    ^                                   ^
    |      “i” não existe neste escopo! +
    + “i” só existe neste escopo.
SIP-16: Macros
// Type (class/trait) macros

class User extends DbTable(jdbcUrl, “t_user”)
                   ^
                   + Macro

// Banco de dados é consultado durante
// compilação para geração do corpo da
// classe “User”
SIP-16: Macros
 Type macros são similares aos type providers de F#



 Só que mais. ;-)



 Versão experimental de SLICK (ex-ScalaQuery)
  implementada com versão experimental de type
  macros
SIP-16: Macros
// Macro annotations

@memoize
def fat(n: Int) =
  if (n > 0) n * fat(n – 1)
  else 1

// Macro aplicada ao elemento anotado,
// seja ele classe, método, parâmetro, etc
SIP-16: Macros
   Somente typed macros disponibilizadas...
   Experimentalmente...
   Atrás do flag –language:experimental.macros...
   Mas várias partes da biblioteca padrão já as estão
    usando!
   Por outro lado, tornar macros fáceis não foi um dos
    objetivos...
   De propósito...
   Trauma das “macros” do C/C++ muito difuso...
   ...mas as verdadeiras macros do C++ são os templates!
SIP-16: Macros
 Vantagens de Typed Macros:
    Relativamente simples de implementar
    Assinatura de método implementado com macro não
     tem nenhuma diferença!
       Facilidade para testar
   Higiene provida através de macro!
   Macros não higiênicas fáceis de criar
SIP-16: Macros
 Desvantagens:
   Limites no que é possível
   Compilação em dois estágios
       Não é possível compilar uma macro e usá-la em um único
        passo
   Não-higienica por default
   Quem é do contra vai continuar achando ruim
SIP-16: Macros
object Trimmer {
  def trim(s: String): String = macro trimImpl

    import scala.reflect.makro.Context
    def trimImpl(c: Context)(s: c.Expr[String]): c.Expr[String] = {
      import c.universe._ // see reflection

        val Literal(Constant(untrimmed: String)) = s.tree
        val trimmed = untrimmed.lines.map(_.trim).mkString("n")

        c.Expr(Literal(Constant(trimmed)))
    }
}
SIP-16: Macros
 Tipos de métodos dependentes de tipos:
    def m(c: Context)(param: c.Expr[Any]):
     c.Expr[Any]
 Opção –Ydependent-method-types em versões
  anteriores
 Reflexão, reflexão e reflexão! 
 “Uma vez que temos reflexão direito, macros vem de
  graça!” – parafraseando Martin Odersky
SIP-17: Tipo Dynamic
 Problema: a integração de Scala com outras linguagens
 assume tipagem estática
   Grande quantidade de alternativas dinâmicas na JVM!
 Solução: trait Dynamic
 Similar ao “missing method”
 Facilita integração com linguagens dinâmicas na JVM
 Mas tem outras utilidades...
SIP-17: Tipo Dynamic
scala> class xmlPath(xml: scala.xml.Node) extends Dynamic {
     |   def selectDynamic(path: String) = xml  path
     | }
defined class xmlPath

scala> new xmlPath(<root><a><b><c/></b></a></root>).b
res9: scala.xml.NodeSeq = NodeSeq(<b><c/></b>)
SIP-17: Tipo Dynamic
 Conversões:

 Métodos convencionais:
    applyDynamic
 Métodos com nome de parâmetros:
    applyDynamicNamed
 Atribuições (setters):
    updateDynamic
 Valores (getters):
    selectDynamic
SIP-18: Modularização de
Funcionalidades da Linguagem
 Problemas:
    Algumas funcionalidades de Scala são de difícil
     compreensão
    Outras induzem a erros
    E algumas são experimentais
 Mas são todas necessárias, por uma razão ou outra!
 Solução: SIP-18
SIP-18: Modularização de
Funcionalidades da Linguagem
 Controla acesso a certas funcionalidades
 Uso das funcionalidades causa avisos
    Mas podem se tornar erros em futuras versões
 Liberação de uso através de:
    flag de compilação
    valor implícito no escopo
 Liberação pode ser herdada
 ScalaDoc explica prós e contras de cada funcionalidade
SIP-18: Modularização de
Funcionalidades da Linguagem
 Funcionalidades contenciosas
    Operadores pós-fixados
    Chamada de métodos implementadas via reflexão
    Conversões de tipo implícitas
    Higher kinded types
    Existenciais
       Exceto aqueles que equivalem a Java wildcard types
   Tipo Dynamic
 Funcionalidades experimentais
    Macros
SIP-18: Modularização de
Funcionalidades da Linguagem
// Notação de operador pós-fixado

scala> "abc" length
warning: there were 1 feature warnings; re-run with -feature for
details
res0: Int = 3
SIP-18: Modularização de
Funcionalidades da Linguagem
// Notação de operador pós-fixado, com –feature

scala> "abc" length
<console>:8: warning: postfix operator length should be enabled
by making the implicit value language.postfixOps visible.
This can be achieved by adding the import clause 'import
language.postfixOps'
or by setting the compiler option -language:postfixOps.
See the Scala docs for value scala.language.postfixOps for a
discussion
why the feature should be explicitly enabled.
              "abc" length
                     ^
res0: Int = 3
SIP-18: Modularização de
Funcionalidades da Linguagem
// Chamada de métodos implementadas via reflexão
scala> val x = new AnyRef { def hello = println("world") }
x: Object{def hello: Unit} = $anon$1@7d628303

scala> x.hello
<console>:10: warning: reflective access of structural type member method hello
should
 be enabled
by making the implicit value language.reflectiveCalls visible.
This can be achieved by adding the import clause 'import language.reflectiveCalls'
or by setting the compiler option -language:reflectiveCalls.
See the Scala docs for value scala.language.reflectiveCalls for a discussion
why the feature should be explicitly enabled.
               x.hello
                 ^
world
SIP-18: Modularização de
Funcionalidades da Linguagem
// Conversões Implícitas

scala> implicit def f(s: String): Int = Predef.augmentString(s).toInt
<console>:8: warning: implicit conversion method f should be enabled
by making the implicit value language.implicitConversions visible.
This can be achieved by adding the import clause 'import
language.implicitConversions'
or by setting the compiler option -language:implicitConversions.
See the Scala docs for value scala.language.implicitConversions for a
discussion
why the feature should be explicitly enabled.
       implicit def f(s: String): Int = Predef.augmentString(s).toInt
                    ^
f: (s: String)Int
SIP-18: Modularização de
Funcionalidades da Linguagem
 A funcionalidade limitada são as conversões
  implícitas
 Outros usos de implicits continuam liberados (e
  incentivados!)
 E conversões implícitas através de classes implícitas
  também
SIP-18: Modularização de
Funcionalidades da Linguagem
// Higher Kinded Types

scala> class Monad[M[_]]
<console>:9: warning: higher-kinded type should be enabled
by making the implicit value language.higherKinds visible.
This can be achieved by adding the import clause 'import
language.higherKinds'
or by setting the compiler option -language:higherKinds.
See the Scala docs for value scala.language.higherKinds for a
discussion
why the feature should be explicitly enabled.
       class Monad[M[_]]
                    ^
defined class Monad
SIP-18: Modularização de
Funcionalidades da Linguagem
// Existenciais

scala> val l: List[ T forSome { type T }] = List(1)
<console>:7: warning: the existential type T forSome { type T
}, which cannot be expressed by wildcards, should be enabled
by making the implicit value language.existentials visible.
This can be achieved by adding the import clause 'import
language.existentials'
or by setting the compiler option -language:existentials.
See the Scala docs for value scala.language.existentials for a
discussion
why the feature should be explicitly enabled.
       val l: List[ T forSome { type T }] = List(1)
                       ^
l: List[T forSome { type T }] = List(1)
SIP-18: Modularização de
Funcionalidades da Linguagem
// Tipo Dynamic

TODO
SIP-18: Modularização de
Funcionalidades da Linguagem
// Macros

scala> def g(d: Any): Any = macro f
<console>:12: error: macro definition needs to be enabled
by making the implicit value language.experimental.macros
visible.
This can be achieved by adding the import clause 'import
language.experimental.macros'
or by setting the compiler option -language:experimental.macros.
See the Scala docs for value scala.language.experimental.macros
for a discussion
why the feature needs to be explicitly enabled.
       def g(d: Any): Any = macro f
           ^
scala.reflect
 Permitem explorar a estrutura de um programa,
 e interagir com esta estrutura
    Wiki: reflexão ocorre em tempo de execução
    Scala: você usa a mesma biblioteca em tempo de
     compilação, com macros
 Noções fundamentais:
    Bibliotecas de reflexão e Universos
    Nomes, símbolos, tipos, árvores
    Mirrors
scala.reflect – Universos




               Fonte: Scala Reflection Pre-SIP
scala.reflect – Universos
 Contém uma série de elementos interligados que,
 juntos, formam os componentes fundamentais da
 reflexão
   Symbol
   Tree
   Name
   etc...
 Uso de path dependent types para associar tipos aos
 universos dos quais se originaram
scala.reflect – Universos
 Construído com o “cake pattern” em camadas com
 diferentes graus de detalhes:
   Base:
     Conceito fundamentais
     Identidade, e pouco mais

   JavaUniverse
     Manipulação baseada nas facilidades de reflexão provida pela JVM,
      melhorada com informações de Scala
   Makro
     Manipulação em tempo de compilação
     Universo do compilador, mas com uma API mais restrita

   Outros: Compilador
scala.reflect – Tipos Fundamentais
                                    Name

               FlagSet                        Symbol




                               Universo
        AnnotationInfo
                                                  Type


                         Position          Tree
scala.reflect – Name

           Name

 TermName        TypeName
scala.reflect – Name
 Scala possui dois espaços de nome:
    Tipos
    Valores (Term)
 Name associa uma string a um desses dois espaços
 Name também permite converter entre a representação
 na linguagem, e a representação nos class files
scala.reflect – Symbol
                 Symbol
          Type         owner         Name


 Symbol   Type   ...   Symbol   TermName   TypeName
scala.reflect – Symbol
 Todas definições estão associadas a símbolos
    Classes
    Métodos
    Parâmetros
    Variáveis
    Se você deu um nome, tem um símbolo
    Se você não deu um nome, mas chama de “anônimo”,
     tem um símbolo também
 Mutável no compilador, imutável em tempo de
 execução
scala.reflect – Type
 Representa a estrutura associada a um tipo:
    Membros das classes
    Parâmetros e tipo de retorno de um método
    etc
 Formado por case classes imutáveis
 Manipulado através de pattern matching
scala.reflect – Tipos e Símbolos
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> typeOf[List[Int]]
res0: reflect.runtime.universe.Type = List[Int]

scala> res0.member(newTermName("head"))
res1: reflect.runtime.universe.Symbol = method head

scala> res1.typeSignature
res2: reflect.runtime.universe.Type = => A

scala> res1.typeSignatureIn(res0)
res3: reflect.runtime.universe.Type = => Int
scala.reflect – Tipos e Símbolos
def intMethods[T : TypeTag](v: T) = {
  val IntType = typeOf[Int]
  val vType   = typeOf[T]
  val methods = vType.nonPrivateMembers.collect {
    case m: MethodSymbol => m -> m.typeSignatureIn(vType)
  }
  methods collect {
    case (m, mt @ NullaryMethodType(IntType))          => m -> mt
    case (m, mt @ MethodType(_, IntType))              => m -> mt
    case (m, mt @ PolyType(_, MethodType(_, IntType))) => m -> mt
  }
}
scala.reflect – Tipos e Símbolos
def intMethods[T : TypeTag](v: T) = {
  val IntType = typeOf[Int]
  val vType   = typeOf[T]
  val methods = vType.nonPrivateMembers.collect {
    case m: MethodSymbol => m -> m.typeSignatureIn(vType)
  }
  methods collect {
    case (m, mt @ NullaryMethodType(IntType))          => m -> mt
    case (m, mt @ MethodType(_, IntType))              => m -> mt
    case (m, mt @ PolyType(_, MethodType(_, IntType))) => m -> mt
  }
}
scala.reflect – Tipos e Símbolos
// Na verdade, você precisa disso:

case (m, mt @ NullaryMethodType(tpe)) if tpe =:= IntType =>
scala.reflect – Tree

        TypTree               Tree           TermTree

             children                 Type    Position   Symbol




 Tree     Tree          ...    Tree
scala.reflect – Tree
 São a representação interna do compilador do código
  fonte
 Imutável, formado por case classes
 Essencial ao se lidar com macros
 Usado para annotated typed na biblioteca básica
scala.reflect – Tree
scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox

scala> import scala.reflect.runtime.{currentMirror => m}
import scala.reflect.runtime.{currentMirror=>m}

scala> val tb = m.mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] =
scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@5bbdee69

scala> val tree = tb.parseExpr("1 to 3 map (_+1)")
tree: tb.u.Tree = 1.to(3).map(((x$1) => x$1.$plus(1)))

scala> val eval = tb.runExpr(tree)
eval: Any = Vector(2, 3, 4)
scala.reflect – Tree
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> showRaw(reify({ def f(x: Int, y: Int) = x + y }).tree)
res4: String = Block(List(DefDef(Modifiers(), newTermName("f"),
List(), List(List(ValD
ef(Modifiers(PARAM), newTermName("x"), Ident(scala.Int),
EmptyTree), ValDef(Modifiers(
PARAM), newTermName("y"), Ident(scala.Int), EmptyTree))),
TypeTree(), Apply(Select(Ide
nt(newTermName("x")), newTermName("$plus")),
List(Ident(newTermName("y")))))), Literal
(Constant(())))
scala.reflect – Mirror

                    InstanceMirror                         ClassMirror




                                                           MethodMirror
 ClassMirror   FieldMirror   MethodMirror   ModuleMirror
                                                           (constructors)
scala.reflect – Mirror
 Mirrors permitem manipulação de instâncias e classes
    em tempo de execução
   Cada Universe pode ter um ou mais mirrors
   Cada mirror está associado a um class loader
   Classes de mesmo nome podem existir carregadas por
    class loaders distintos
   Mirrors permitem manipulação baseada na linguagem
    Scala, e não em sua implementação na JVM
scala.reflect – Mirror
val obj = "String"
val objClass = obj.getClass
val classClassLoader = objClass.getClassLoader
val classLoaderMirror = runtimeMirror(classClassLoader)
val classSymbol = classLoaderMirror.classSymbol(objClass)
val classType = classSymbol.typeSignature
val methodName = newTermName("length")
val methodSymbol = classType.member(methodName).asMethodSymbol
val instanceMirror = classLoaderMirror.reflect(obj)
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
methodMirror.apply() // == (obj.length: Any)
Atores e Akka???
 A biblioteca padrão deixará de existir
    Substituída pelo Akka
    Quando???
 A biblioteca Akka fará parte da distribuição 2.10
    Somente binários – código fonte permanece separado
 Será disponibilizado um guia de migração
 A biblioteca padrão virá com um “kit” para facilitar a
  migração
   Para que serve?
Scala 2.10.0
Especulações
 untyped macros
    for { val x = 0; x < 10; x += 1 } println(x)
 macro types
    class X extends MacroClassY(parm)
 macro annotations
    @memoize def fat(n: Int) = if (n > 0) n *
     fat(n -1) else 1
 effect system
 integração de abstract types e type parameters.
 pré-processador (DOA!)

Mais conteúdo relacionado

Destaque

Scala For Java Programmers
Scala For Java ProgrammersScala For Java Programmers
Scala For Java ProgrammersEnno Runne
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Why Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data WorldWhy Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data WorldDean Wampler
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaVladimir Kostyukov
 
Building microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootBuilding microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootChris Richardson
 
Advanced Functional Programming in Scala
Advanced Functional Programming in ScalaAdvanced Functional Programming in Scala
Advanced Functional Programming in ScalaPatrick Nicolas
 
Introduction to Scala for Java Developers
Introduction to Scala for Java DevelopersIntroduction to Scala for Java Developers
Introduction to Scala for Java DevelopersMichael Galpin
 
Streaming Big Data with Spark, Kafka, Cassandra, Akka & Scala (from webinar)
Streaming Big Data with Spark, Kafka, Cassandra, Akka & Scala (from webinar)Streaming Big Data with Spark, Kafka, Cassandra, Akka & Scala (from webinar)
Streaming Big Data with Spark, Kafka, Cassandra, Akka & Scala (from webinar)Helena Edelson
 
Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...
Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...
Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...Helena Edelson
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scalapramode_ce
 

Destaque (12)

Scala For Java Programmers
Scala For Java ProgrammersScala For Java Programmers
Scala For Java Programmers
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Why Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data WorldWhy Scala Is Taking Over the Big Data World
Why Scala Is Taking Over the Big Data World
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Why Scala?
Why Scala?Why Scala?
Why Scala?
 
Building microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring BootBuilding microservices with Scala, functional domain models and Spring Boot
Building microservices with Scala, functional domain models and Spring Boot
 
Advanced Functional Programming in Scala
Advanced Functional Programming in ScalaAdvanced Functional Programming in Scala
Advanced Functional Programming in Scala
 
Introduction to Scala for Java Developers
Introduction to Scala for Java DevelopersIntroduction to Scala for Java Developers
Introduction to Scala for Java Developers
 
Streaming Big Data with Spark, Kafka, Cassandra, Akka & Scala (from webinar)
Streaming Big Data with Spark, Kafka, Cassandra, Akka & Scala (from webinar)Streaming Big Data with Spark, Kafka, Cassandra, Akka & Scala (from webinar)
Streaming Big Data with Spark, Kafka, Cassandra, Akka & Scala (from webinar)
 
Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...
Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...
Lambda Architecture with Spark, Spark Streaming, Kafka, Cassandra, Akka and S...
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 

Semelhante a Scala 2.10.0

VRaptor - Ciclo CASIN 2011
VRaptor - Ciclo CASIN 2011VRaptor - Ciclo CASIN 2011
VRaptor - Ciclo CASIN 2011Daniel Kist
 
Praticando o Desapego: quando ignorar a dívida técnica
Praticando o Desapego: quando ignorar a dívida técnicaPraticando o Desapego: quando ignorar a dívida técnica
Praticando o Desapego: quando ignorar a dívida técnicaIvayr Farah Netto
 
SQL_e_banco_de_dados_Oracle_SQL_Uma_abor.pdf
SQL_e_banco_de_dados_Oracle_SQL_Uma_abor.pdfSQL_e_banco_de_dados_Oracle_SQL_Uma_abor.pdf
SQL_e_banco_de_dados_Oracle_SQL_Uma_abor.pdfEulimarTiburcio
 
Workshop Performance Rails
Workshop Performance RailsWorkshop Performance Rails
Workshop Performance RailsVitor Pellegrino
 
Java web fj21-- apostila da caelum
Java web fj21-- apostila da caelumJava web fj21-- apostila da caelum
Java web fj21-- apostila da caelumAgenor Neto
 
Inovações Na Plataforma Java
Inovações Na Plataforma JavaInovações Na Plataforma Java
Inovações Na Plataforma JavaFilipe Portes
 
Nem tudo é Pepino: Cucumber x Robot Framework
Nem tudo é Pepino: Cucumber x Robot FrameworkNem tudo é Pepino: Cucumber x Robot Framework
Nem tudo é Pepino: Cucumber x Robot FrameworkRodrigo Matola
 
Scrum Gathering Rio 2016 - Conteinerizando Testes com Docker Compose
Scrum Gathering Rio 2016 - Conteinerizando Testes com Docker ComposeScrum Gathering Rio 2016 - Conteinerizando Testes com Docker Compose
Scrum Gathering Rio 2016 - Conteinerizando Testes com Docker ComposeStefan Teixeira
 
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...Vagner Nogueira
 
Bigdata e NoSQL: buzzwords da teoria à prática
Bigdata e NoSQL: buzzwords da teoria à práticaBigdata e NoSQL: buzzwords da teoria à prática
Bigdata e NoSQL: buzzwords da teoria à práticaFabíola Fernandes
 
Infinispan - Distribuição de Dados com Java
Infinispan - Distribuição de Dados com JavaInfinispan - Distribuição de Dados com Java
Infinispan - Distribuição de Dados com JavaWagner Roberto dos Santos
 
Novidades do Universo MySQL julho-15
Novidades do Universo MySQL julho-15Novidades do Universo MySQL julho-15
Novidades do Universo MySQL julho-15MySQL Brasil
 
Arquitetura de Memoria do PostgreSQL
Arquitetura de Memoria do PostgreSQLArquitetura de Memoria do PostgreSQL
Arquitetura de Memoria do PostgreSQLRaul Oliveira
 
Caelum ruby-on-rails-rr71
Caelum ruby-on-rails-rr71Caelum ruby-on-rails-rr71
Caelum ruby-on-rails-rr71Ana Luiza
 
HTML, CSS & JS: olhando pra frente
HTML, CSS & JS: olhando pra frenteHTML, CSS & JS: olhando pra frente
HTML, CSS & JS: olhando pra frenteLuiz Oliveira
 
Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Caique Moretto
 

Semelhante a Scala 2.10.0 (20)

VRaptor - Ciclo CASIN 2011
VRaptor - Ciclo CASIN 2011VRaptor - Ciclo CASIN 2011
VRaptor - Ciclo CASIN 2011
 
20220093 scilab-manual
20220093 scilab-manual20220093 scilab-manual
20220093 scilab-manual
 
Introdução ao SciLab
Introdução ao SciLabIntrodução ao SciLab
Introdução ao SciLab
 
Praticando o Desapego: quando ignorar a dívida técnica
Praticando o Desapego: quando ignorar a dívida técnicaPraticando o Desapego: quando ignorar a dívida técnica
Praticando o Desapego: quando ignorar a dívida técnica
 
SQL_e_banco_de_dados_Oracle_SQL_Uma_abor.pdf
SQL_e_banco_de_dados_Oracle_SQL_Uma_abor.pdfSQL_e_banco_de_dados_Oracle_SQL_Uma_abor.pdf
SQL_e_banco_de_dados_Oracle_SQL_Uma_abor.pdf
 
Workshop Performance Rails
Workshop Performance RailsWorkshop Performance Rails
Workshop Performance Rails
 
Caelum java-web-fj21
Caelum java-web-fj21Caelum java-web-fj21
Caelum java-web-fj21
 
Java web fj21-- apostila da caelum
Java web fj21-- apostila da caelumJava web fj21-- apostila da caelum
Java web fj21-- apostila da caelum
 
Inovações Na Plataforma Java
Inovações Na Plataforma JavaInovações Na Plataforma Java
Inovações Na Plataforma Java
 
Nem tudo é Pepino: Cucumber x Robot Framework
Nem tudo é Pepino: Cucumber x Robot FrameworkNem tudo é Pepino: Cucumber x Robot Framework
Nem tudo é Pepino: Cucumber x Robot Framework
 
Scrum Gathering Rio 2016 - Conteinerizando Testes com Docker Compose
Scrum Gathering Rio 2016 - Conteinerizando Testes com Docker ComposeScrum Gathering Rio 2016 - Conteinerizando Testes com Docker Compose
Scrum Gathering Rio 2016 - Conteinerizando Testes com Docker Compose
 
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
 
Bigdata e NoSQL: buzzwords da teoria à prática
Bigdata e NoSQL: buzzwords da teoria à práticaBigdata e NoSQL: buzzwords da teoria à prática
Bigdata e NoSQL: buzzwords da teoria à prática
 
Infinispan - Distribuição de Dados com Java
Infinispan - Distribuição de Dados com JavaInfinispan - Distribuição de Dados com Java
Infinispan - Distribuição de Dados com Java
 
Novidades do Universo MySQL julho-15
Novidades do Universo MySQL julho-15Novidades do Universo MySQL julho-15
Novidades do Universo MySQL julho-15
 
Arquitetura de Memoria do PostgreSQL
Arquitetura de Memoria do PostgreSQLArquitetura de Memoria do PostgreSQL
Arquitetura de Memoria do PostgreSQL
 
Caelum ruby-on-rails-rr71
Caelum ruby-on-rails-rr71Caelum ruby-on-rails-rr71
Caelum ruby-on-rails-rr71
 
As novidades da nova versão do Java 9
As novidades da nova versão do Java 9As novidades da nova versão do Java 9
As novidades da nova versão do Java 9
 
HTML, CSS & JS: olhando pra frente
HTML, CSS & JS: olhando pra frenteHTML, CSS & JS: olhando pra frente
HTML, CSS & JS: olhando pra frente
 
Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28Caelum java-web-vraptor-hibernate-ajax-fj28
Caelum java-web-vraptor-hibernate-ajax-fj28
 

Mais de Daniel Sobral

What can scala puzzlers teach us
What can scala puzzlers teach usWhat can scala puzzlers teach us
What can scala puzzlers teach usDaniel Sobral
 
Injecting Clock in Java
Injecting Clock in JavaInjecting Clock in Java
Injecting Clock in JavaDaniel Sobral
 
A JSR-310 Date: Beyond JODA Time
A JSR-310 Date: Beyond JODA TimeA JSR-310 Date: Beyond JODA Time
A JSR-310 Date: Beyond JODA TimeDaniel Sobral
 
Gestão automática de configuração usando puppet
Gestão automática de configuração usando puppetGestão automática de configuração usando puppet
Gestão automática de configuração usando puppetDaniel Sobral
 
Palestra ganeti puppet
Palestra ganeti puppetPalestra ganeti puppet
Palestra ganeti puppetDaniel Sobral
 
Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distr...
Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distr...Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distr...
Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distr...Daniel Sobral
 

Mais de Daniel Sobral (9)

What can scala puzzlers teach us
What can scala puzzlers teach usWhat can scala puzzlers teach us
What can scala puzzlers teach us
 
Injecting Clock in Java
Injecting Clock in JavaInjecting Clock in Java
Injecting Clock in Java
 
A JSR-310 Date: Beyond JODA Time
A JSR-310 Date: Beyond JODA TimeA JSR-310 Date: Beyond JODA Time
A JSR-310 Date: Beyond JODA Time
 
Gestão automática de configuração usando puppet
Gestão automática de configuração usando puppetGestão automática de configuração usando puppet
Gestão automática de configuração usando puppet
 
Palestra ganeti puppet
Palestra ganeti puppetPalestra ganeti puppet
Palestra ganeti puppet
 
Tutorial Puppet
Tutorial PuppetTutorial Puppet
Tutorial Puppet
 
Regex
RegexRegex
Regex
 
Introdução a TDD
Introdução a TDDIntrodução a TDD
Introdução a TDD
 
Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distr...
Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distr...Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distr...
Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distr...
 

Scala 2.10.0

  • 1. De onde viemos e para onde vamos? Daniel Capó Sobral
  • 2. Quem sou eu?  Daniel C. Sobral @ Stack Overflow  dcsobral @ Twitter, Gmail/Gtalk, Skype, SliderShare  Daniel Sobral @ Facebook, Speakers Deck, LinkedIn  http://www.linkedin.com/in/danielsobral  http://www.slideshare.net/dcsobral  https://speakerdeck.com/u/dcsobral  http://dcsobral.blogspot.com
  • 3. O que eu sei de Scala?  Scala gold badge @ Stack Overflow  Pequenas contribuições para Scala:  otimizações  funcionalidades  bug fixes  documentação (nem tão pequenas)  Participante ativo da comunidade Scala (listas de discussão, irc)  Blog
  • 4. IMPORTANTE!  Scala 2.10.0 ainda não foi lançada!  Na data em que esta apresentação foi escrita... (07/07/2012)  As informações contidas nessa apresentação podem mudar antes do lançamento.
  • 5. Sumário  Histórico  Futuro Imediato  Versionamento  Processo de Release  Bug fixes  Melhorias  SIPs (Scala Improvement Process)  Reflection  Atores e Akka  Futuro Distante
  • 7. Histórico 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 • 0.8.1 • 1.0.0 • 1.4.0 • 2.0.0 • 2.3.2 • 2.7.1 • 2.7.3 • 2.8.0 • 2.9.0 • 2.9.2 • 0.8.2 • 1.1.0 • 2.1.0 • 2.3.3 • 2.7.2 • 2.7.4 • 2.8.1 • 2.9.1 • 0.9.0 • 1.1.0 • 2.1.1 • 2.4.0 • 2.7.5 • 2.8.2 • 0.9.1 • 1.1.1 • 2.1.2 • 2.5.0 • 2.7.6 • 1.2.0 • 2.1.3 • 2.5.1 • 2.7.7 • 1.3.0 • 2.1.5 • 2.6.0 • 2.1.6 • 2.6.1 • 2.1.7 • 2.1.8 • 2.2.0 • 2.3.0 • 2.3.1
  • 8. Alguns marcos importantes 2011 • Parallel Collections 2010 • Novo design de Collections • Compatibilidade Binária 2008 • Java Generics • Case Class Extractors 2007 • Extractors • Private/protected primary constructors • Private[this] • Placeholder 2006 parameters • Scalac escrito em • Early Initialization Scala • Abstract Type • Implicits Constructors • Traits e • Existential Types linearização • Lazy values • Multilline Strings • Structural Types
  • 10. Explicando Versionamento 2 .9 .1 -1 Bug Epoch Major Minor fix
  • 11. Versionamento – Scala 2.10.0  Major release  Binariamente incompatível  Mudanças de linguagem  Mudanças de biblioteca  Novas depreciações  Remoção de características depreciadas (deprecated)  Classes  Métodos  Características da linguagem
  • 12. Exemplos de Novas Depreciações  Números octais! scala> 077 <console>:1: warning: Treating numbers with a leading zero as octal is deprecated. 077 ^ res10: Int = 63  Double terminando em ponto scala> 1. <console>:1: warning: This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit. 1. ^ res11: Double = 1.0
  • 13. Exemplos de Depreciações Removidas  Características de linguagem for ( val i <- 1 to 10) println(i)  Classe scala.collection.mutable.CloneableCollection  Método scala.collection.immutable.Queue.+  Pacotes scala.testing.SUnit
  • 14. Melhoria no processo de release  Processo cada vez mais automatizado  Pacotes RPM, APT, Brew, etc  Geração automática!  Uso de Milestones para integrar ferramentas de terceiros  M4 dia 12 de Junho  M5 em breve  Release Candidates para consolidar e eliminar bugs
  • 15. Bug fixes  Muitas correções!  Novo código do pattern matcher!  Priorização da correção de tickets!  Novos warnings:  Detectando bugs no próprio compilador!  Mais contribuições de terceiros!  git + pull request == FTW  ...em adição ao processo natural de melhoria da linguagem.
  • 16. Tickets fechados 102 451 490 622 896 963 1118 1133 1195 1201 1247 1336 1430 1431 1432 1439 1510 1785 1799 2089 2094 2171 2196 2308 2322 2337 2388 2405 2435 2442 2460 2764 2782 2807 3047 3048 3098 3240 3272 3326 3343 3371 3392 3481 3566 3569 3628 3702 3708 3718 3755 3758 3761 3770 3798 3853 3854 3880 3898 3929 3960 3999 4018 4019 4025 4027 4063 4070 4098 4110 4124 4134 4147 4171 4172 4176 4216 4262 4270 4271 4273 4319 4326 4336 4355 4372 4391 4398 4417 4419 4425 4430 4441 4461 4467 4469 4478 4482 4490 4494 4501 4510 4512 4515 4535 4540 4541 4542 4547 4553 4561 4568 4570 4573 4574 4578 4579 4584 4592 4593 4595 4599 4601 4627 4636 4642 4647 4651 4656 4658 4661 4692 4696 4697 4709 4712 4713 4716 4717 4723 4727 4731 4737 4740 4749 4753 4757 4758 4759 4761 4764 4766 4770 4777 4780 4792
  • 17. Tickets fechados 4794 4800 4802 4804 4807 4809 4811 4818 4823 4827 4828 4831 4833 4839 4842 4846 4851 4853 4857 4858 4859 4860 4861 4869 4871 4874 4875 4877 4879 4882 4891 4894 4898 4899 4909 4910 4911 4925 4928 4929 4933 4935 4938 4954 4957 4959 4961 4963 4970 4975 4976 4979 4981 4985 4987 4989 5005 5009 5012 5018 5020 5023 5026 5029 5032 5033 5034 5037 5040 5041 5053 5054 5056 5062 5063 5066 5071 5072 5077 5078 5080 5083 5084 5085 5093 5096 5097 5099 5104 5105 5108 5117 5119 5121 5125 5127 5135 5137 5147 5148 5152 5156 5162 5165 5167 5168 5175 5176 5178 5189 5199 5201 5205 5206 5210 5212 5215 5223 5226 5229 5230 5239 5245 5248 5256 5259 5266 5267 5272 5284 5287 5291 5293 5295 5300 5305 5313 5317 5318 5328 5334 5336 5341 5343 5344 5352 5354 5356 5358 5359 5373 5374 5375 5377 5382 5384
  • 18. Tickets fechados (442 – 02/Jul) 5387 5399 5405 5406 5407 5426 5428 5429 5441 5444 5446 5451 5452 5453 5455 5471 5488 5489 5497 5500 5510 5514 5522 5528 5530 5532 5535 5537 5542 5543 5544 5545 5552 5553 5554 5564 5571 5572 5577 5578 5580 5589 5590 5591 5593 5599 5608 5609 5610 5612 5614 5617 5623 5626 5627 5629 5632 5640 5641 5644 5648 5652 5654 5655 5656 5663 5666 5667 5672 5676 5677 5680 5682 5683 5688 5689 5690 5693 5696 5702 5703 5704 5706 5707 5708 5713 5715 5720 5728 5729 5735 5738 5742 5760 5761 5763 5769 5777 5779 5796 5801 5804 5805 5809 5816 5821 5829 5839 5840 5843 5845 5846 5853 5857 5862 5867 5879 5880 5881 5899 5910 5912 5914 5932 5953 5966 5967 5968 5971 5986 etc?
  • 19. Melhorias  Novas coleções  Mutable SortedSet/SortedMap (baseadas em AVL)  Mutable Concurrent Map (TrieMap)  Parallel Mutable Concurrent Map (ParTrieMap)  Performance:  Immutable SortedSet/SortedMap  Novo (private) RedBlackTree  TreeIterator  PartialFunction  applyOrElse  BitSet  MurmurHash3 (coleções, xml, case classes)
  • 20. Novidades  Type Classes:  Try (alternativa do Twitter ao Either)  Hashing (já existe Equiv)  IsTraversableOnce e IsTraversableLike  Pacote scala.util.hashing  Pools configuráveis em coleções paralelas  @unspecialized  to[Collection]  ???
  • 21. Novidades  override object (-Yoverride-objects)  Bytecode versão 49, 50 e 51 (-target:jvm-1.x-asm)  -optimize mais rápido e eficiente  -Dscala.timings=true revela quais são os pontos de demora na compilação  SIP-18: -language:XXX, -feature  logs variados  macro variados  patmat variados  etc...
  • 22. scala.util.Try def percentCompleted(total: Int, done: Int): Int = Try ( done * 100 / total ) getOrElse 100
  • 23. scala.util.Try Try { new FileInputStream(a) } rescue { case _: FileNotFoundException => new FileInputStream(b) } recover { case _: FileNotFoundException => defaultInputStream } andThen { stream => in = stream.read(); Stream.close(); in }
  • 24. scala.util.hashing.Hashing def hashingOf[T : Hashing](obj: T): Int = implicitly[Hashing[T]].hash(obj) // Uma função de hashing ruim para Seqs implicit val seqHashing = Hashing fromFunction ((_: Seq[_]).size)
  • 25. IsTraversableOnce IsTraversableLike class FilterMapImpl[A, Repr] (val r: GenTraversableLike[A, Repr]) { final def filterMap[B, That] (f: A => Option[B]) (implicit cbf: CanBuildFrom[Repr, B, That]) : That = r.flatMap(f(_).toSeq) } // Como escrever a conversão implícita???
  • 26. IsTraversableOnce IsTraversableLike  Problemas em se escrever a conversão:  Array e String não são GenTraversable  String não possui parâmetro de elemento (A)  Nem BitSet e outras coleções  Inferência sobre view bounds é deficiente
  • 27. IsTraversableOnce IsTraversableLike class FilterMapImpl[A, Repr] (val r: GenTraversableLike[A, Repr]) { final def filterMap[B, That] (f: A => Option[B]) (implicit cbf: CanBuildFrom[Repr, B, That]) : That = r.flatMap(f(_).toSeq) } implicit def filterMap[Repr, A](r: Repr) (implicit fr: IsTraversableOnce[Repr]) : FilterMapImpl[fr.A,Repr] = new FilterMapImpl(fr.conversion(r))
  • 28. Pools Configuráveis em Coleções Paralelas import scala.collection.parallel._ val pc = mutable.ParArray(1, 2, 3) pc.tasksupport = new ForkJoinTaskSupport( new scala.concurrent.ForkJoinPool(2)) pc map { _ + 1) pc.tasksupport = new ThreadPoolTaskSupport()
  • 29. Pools Configuráveis em Coleções Paralelas – Customizando class customTaskSupport extends TaskSupport { def execute[R, Tp] (task: Task[R, Tp]): () => R = ??? def executeAndWaitResult[R, Tp] (task: Task[R, Tp]): R = ??? def parallelismLevel: Int = ??? }
  • 30. to[Collection] scala> List(2, 1, 3).to[Seq] res17: Seq[Int] = Vector(2, 1, 3) scala> List(2, 1, 3).to[Vector] res18: Vector[Int] = Vector(2, 1, 3) scala> List(2, 1, 3).to[collection.mutable.Seq] res19: scala.collection.mutable.Seq[Int] = ArrayBuffer(2, 1, 3) scala> List(2, 1, 3).to[collection.immutable.SortedSet] res20: scala.collection.immutable.SortedSet[Int] = TreeSet(1, 2, 3)
  • 31. ???  ??? é um método do tipo Nothing que lança uma exceção  Por ser do tipo Nothing, ??? pode aparecer no lugar de qualquer expressão  Excelente para stubs, exercícios e apresentações!
  • 32. ??? trait Opt [A] { // Exercise by Tony Morris def fold[X](some: A => X, none: => X): X = ??? def map[B](f: A => B): Opt[B] = ??? def get: A = ??? def flatMap[B](f: A => Opt[B]): Opt[B] = ??? def mapAgain[B](f: A => B): Opt[B] = ??? def getOrElse(e: => A): A = ??? def filter(p: A => Boolean): Optional[A] = ??? def exists(p: A => Boolean): Boolean = ??? def forall(p: A => Boolean): Boolean = ??? def foreach(f: A => Unit): Unit = ??? def isDefined: Boolean = ??? def orElse(o: => Opt[A]): Opt[A] = ??? // etc Adaptado de Tony Morris, http://blog.tmorris.net/further-understanding-scalaoption/
  • 33. ??? trait Opt [A] { // Exercise by Tony Morris def fold[X](some: A => X, none: => X): X = ??? def map[B](f: A => B): Opt[B] = ??? def get: A = ??? def flatMap[B](f: A => Opt[B]): Opt[B] = ??? def mapAgain[B](f: A => B): Opt[B] = ??? def getOrElse(e: => A): A = ??? def filter(p: A => Boolean): Optional[A] = ??? def exists(p: A => Boolean): Boolean = ??? def forall(p: A => Boolean): Boolean = ??? def foreach(f: A => Unit): Unit = ??? def isDefined: Boolean = ??? def orElse(o: => Opt[A]): Opt[A] = ??? // etc Adaptado de Tony Morris, http://blog.tmorris.net/further-understanding-scalaoption/
  • 34. Melhorias  Scaladoc  Implicits!  Diagramas!  API docs
  • 38. Parâmetros para ScalaDoc  -implicits  -diagrams  Esse slide foi exigência de Vlad Ureche ;-)
  • 39. SIP – Scala Improvement Process  SIP-11: String Interpolation  SIP-12: Sintaxe das Estruturas de Controle  SIP-13: Classes Implicitas  SIP-14: Futures e Promises  SIP-15: Value Classes  SIP-16: Macros auto-limpantes  SIP-17: Tipo Dynamic  SIP-18: Modularização de funcionalidades da linguagem  SIP-19: Posição de Código Fonte Implícitas
  • 40. SIP – Scala Improvement Process  SIP-11: String Interpolation (aceita!)  SIP-12: Sintaxe das Estruturas de Controle (adiada)  SIP-13: Classes Implicitas (aceita!)  SIP-14: Futures e Promises (aceita!)  SIP-15: Value Classes (aceita!)  SIP-16: Macros auto-limpantes (adiada)  SIP-17: Tipo Dynamic (aceita!)  SIP-18: Modularização de funcionalidades da linguagem (aceita!)  SIP-19: Posição de Código Fonte Implícitas (recusada)
  • 41. SIP-11: String Interpolation  Ausência de interpolação de strings motivo de constante reclamações  Mas bem poucas linguagens suportam!  Odersky diz que diferença entre ${x} e "+x+" é de um único caracter  Mas ignora os shifts...  Alegação de que " e + no teclado Suíco não precisa de shift  Verdade!  Reviravolta:  E se interpolação de strings for mais do que interpolação de strings?
  • 42. SIP-11: String Interpolation def hello(name: String = "world"): String = "Hello, " + name + "! " // Interpolation! def hello(name: String = "world"): String = s"Hello, $name! "
  • 43. SIP-11: String Interpolation def percentCompleted(total: Int, done: Int): String = Try ( done * 100 / total ) map { percent => f"$percent%2d% completed" } getOrElse "100% completed" def percentCompleted(total: Int, done: Int): String = Try ( f"${ done * 100 / total }%2d% completed" ) getOrElse "100% completed"
  • 44. SIP-11: String Interpolation: Como funciona? s"Hello, $name!" // traduzido para StringContext("Hello, ", "!").s(name) f"${ done * 100 / total }%2d% completed" // traduzido para StringContext("", "%2d% completed").f(done * 100 / total)
  • 45. SIP-11: String Interpolation  Literais multi-linha também são aceitos  s"""Ok!"""  Interpolação pode ser aninhada  s"${ s"$x" }"  Contra-barra não é interpretada  r"d+/$mes" // interpolador r não existe!  StringContext("""d+/""").r(mes)  Mas s e f interpretam as barras!  s"Hello, $name!n" // newline normal  Formas de alterar comportamento:  Adição de métodos implícitos à StringContext  Sobreposição de objeto ou método chamado StringContext  “r” não precisa ser método!
  • 46. SIP-11: String Interpolation // Adição de interpolação via implicit class RegexContext(sc: StringContext) { def r(args: Any*) = { sc.checkLengths(args: _*) val res = (args, sc.parts.tail).zipped map { (arg, part) => s"Q$argE$part" } mkString "" (sc.parts.head + res).r } } implicit def toRC(sc: StringContext) = new RegexContext(sc)
  • 47. SIP-11: String Interpolation // Aninhamento de interpoladores class RegexContext(sc: StringContext) { def r(args: Any*) = { sc.checkLengths(args: _*) s"${sc.parts.head}${ (args, sc.parts.tail).zipped map { (arg, part) => s"Q$argE$part" } mkString "" }".r } } implicit def toRC(sc: StringContext) = new RegexContext(sc)
  • 48. SIP-11: String Interpolation // Adição de interpolação via sobreposição object StringContext(parts: String*) { def r(args: Any*) = { require(parts.length == args.length + 1) val res = (args, parts.tail).zipped map { "Q" + _ + "E" + _ } mkString "" (parts.head + res).r } } // Possível alterar s e f!
  • 49. SIP-11: String Interpolation // apply e unapplySeq def hello(name: String = "world"): String = i"Hello, $name!" def who(message: String): String = message match { case i"Hello, $name!" => name case _ => “no clue" } who(hello("Daniel")) == "Daniel"
  • 50. SIP-11: String Interpolation // apply e unapplySeq implicit class SI(sc: StringContext) { object i { def apply(args: Any*): String = sc.parts.head + (args,sc.parts.tail).zipped.map(_+_).mkString def unapplySeq(s: String): Option[Seq[String]] = { val partsr = sc.parts map (p => s"Q$pE") val r = (partsr mkString "(.*)").r s match { case r(xs @ _*) => Some(xs) case _ => None } } } }
  • 51. SIP-13: Classes Implícitas  “Enrich My Library” (antigo “Pimp My Library”) extremamente popular  Mas cerimonioso...  “Extension methods” se tornando comuns em outras linguagens  E com menos cerimônia!  Solução: implicit class
  • 52. SIP-13: Classes Implícitas // Adição de interpolação via implicit class implicit class RegexContext(sc: StringContext) { def r(args: Any*) = { sc.checkLengths(args: _*) val res = (args, sc.parts.tail).zipped map { "Q" + _ + "E" + _ } mkString "" (sc.parts.head + res).r } }
  • 53. SIP-14: Futures and Promises  Executar operações em paralelo, de forma não-bloqueante é uma necessidade comum  Evidência: diversas bibliotecas contém implementações de Future  Incluindo a biblioteca padrão de atores!  Problema:  Interface não-padronizada  Dependência de implementação  Solução:  API poderosa e flexível implementando os conceitos de Future e Promise
  • 54. SIP-14: Futures and Promises // TODO – Desculpem! Exemplos da SIP: import scala.concurrent._ val f: Future[List[String]] = future { session.getRecentPosts } f onComplete { case Right(posts) => for (post <- posts) render(post) case Left(t) => render("An error has occured: " + t.getMessage) }
  • 55. SIP-14: Futures and Promises // TODO – Desculpem! Exemplos da SIP: import scala.concurrent._ val f: Future[List[String]] = future { session.getRecentPosts } f onFailure { case t => render("An error has occured: " + t.getMessage) } onSuccess { case posts => for (post <- posts) render(post) }
  • 56. SIP-14: Futures and Promises // TODO – Desculpem! Exemplos da SIP: import scala.concurrent._ def main(args: Array[String]) { val rateQuote = future { connection.getCurrentValue(USD) } val purchase = rateQuote map { quote => if (isProfitable(quote)) connection.buy(amount, quote) else throw new Exception("not profitable") } blocking(purchase, 0 ns) }
  • 57. SIP-14: Futures and Promises // TODO – Desculpem! Exemplos da SIP: import scala.concurrent.{ future, promise } val p = promise[T] val f = p.future val producer = future { val r = produceSomething() p success r continueDoingSomethingUnrelated() } val consumer = future { startDoingSomething() f onSuccess { case r => doSomethingWithResult() } }
  • 58. SIP-15: Value Classes  A maldição das referências  A maldição do boxing:  case class Meter(n: Int) muito mais “caro” que int  A maldição do das classes implícitas:  "abc“.r cria um objeto desnecessário só para chamar new Regex("abc")  Queremos uma classe que não seja referência!  Solução: value classes.
  • 59. SIP-15: Value Classes // Adição de interpolação via implicit value class implicit class RegexContext(sc: StringContext) extends AnyVal { def r(args: Any*) = { sc.checkLengths(args: _*) val res = (args, sc.parts.tail).zipped map { "Q" + _ + "E" + _ } mkString "" (sc.parts.head + res).r } }
  • 60. SIP-15: Value Classes  Só podem ter um parâmetro  O parâmetro deve ser um val  Ou seja, [T: Ordering](v: T) não é aceito  Pode ser estendidas por traits  Se os mesmos estenderem Any ou AnyVal  Não podem definir igualdade ou hash code  Podem ser case classes!  Igualdade e hash code são aplicadas sobre o parâmetro  São efetivamente “final”  Em um escopo local, são removidas por otimização  Se escapam do escopo, são boxed
  • 61. SIP-16: Macros  Compiladores grandes são de difícil manutenção  Pressão contra adição de funcionalidades  Plugins do compilador resolvem...  ...mas são difíceis de manter em sincronia  Possível solução: Macros  “Macros? Ugh!” – trauma do C/C++!  Novidade: scala.reflection  Macros saem quase de graça!
  • 62. SIP-16: Macros  Scala CATs!  Compile-time AST Transformations  Abstract Syntax Tree  Inspirado pelas macros de Nemerle  Quatro tipos cogitados:  Typed macros – Somente este tipo está disponível!  Untyped macros  Type (class/trait) macros  Annotation macros
  • 63. SIP-16: Macros // Typed macros (1 to 5).foreach(println) ^ ^ | + Verificação de tipos + Macro executada + Nova verificação de tipos
  • 64. SIP-16: Macros // Untyped macros for {val i = 0; i < 10; i += 1} println(i) ^ ^ | | | + Tipo dos argumentos não é checado! + Macro executada + Verificação de tipos
  • 65. SIP-16: Macros // Untyped macros – porque? for {val i = 0; i < 10; i += 1} println(i) ^ ^ | “i” não existe neste escopo! + + “i” só existe neste escopo.
  • 66. SIP-16: Macros // Type (class/trait) macros class User extends DbTable(jdbcUrl, “t_user”) ^ + Macro // Banco de dados é consultado durante // compilação para geração do corpo da // classe “User”
  • 67. SIP-16: Macros  Type macros são similares aos type providers de F#  Só que mais. ;-)  Versão experimental de SLICK (ex-ScalaQuery) implementada com versão experimental de type macros
  • 68. SIP-16: Macros // Macro annotations @memoize def fat(n: Int) = if (n > 0) n * fat(n – 1) else 1 // Macro aplicada ao elemento anotado, // seja ele classe, método, parâmetro, etc
  • 69. SIP-16: Macros  Somente typed macros disponibilizadas...  Experimentalmente...  Atrás do flag –language:experimental.macros...  Mas várias partes da biblioteca padrão já as estão usando!  Por outro lado, tornar macros fáceis não foi um dos objetivos...  De propósito...  Trauma das “macros” do C/C++ muito difuso...  ...mas as verdadeiras macros do C++ são os templates!
  • 70. SIP-16: Macros  Vantagens de Typed Macros:  Relativamente simples de implementar  Assinatura de método implementado com macro não tem nenhuma diferença!  Facilidade para testar  Higiene provida através de macro!  Macros não higiênicas fáceis de criar
  • 71. SIP-16: Macros  Desvantagens:  Limites no que é possível  Compilação em dois estágios  Não é possível compilar uma macro e usá-la em um único passo  Não-higienica por default  Quem é do contra vai continuar achando ruim
  • 72. SIP-16: Macros object Trimmer { def trim(s: String): String = macro trimImpl import scala.reflect.makro.Context def trimImpl(c: Context)(s: c.Expr[String]): c.Expr[String] = { import c.universe._ // see reflection val Literal(Constant(untrimmed: String)) = s.tree val trimmed = untrimmed.lines.map(_.trim).mkString("n") c.Expr(Literal(Constant(trimmed))) } }
  • 73. SIP-16: Macros  Tipos de métodos dependentes de tipos:  def m(c: Context)(param: c.Expr[Any]): c.Expr[Any]  Opção –Ydependent-method-types em versões anteriores  Reflexão, reflexão e reflexão!   “Uma vez que temos reflexão direito, macros vem de graça!” – parafraseando Martin Odersky
  • 74. SIP-17: Tipo Dynamic  Problema: a integração de Scala com outras linguagens assume tipagem estática  Grande quantidade de alternativas dinâmicas na JVM!  Solução: trait Dynamic  Similar ao “missing method”  Facilita integração com linguagens dinâmicas na JVM  Mas tem outras utilidades...
  • 75. SIP-17: Tipo Dynamic scala> class xmlPath(xml: scala.xml.Node) extends Dynamic { | def selectDynamic(path: String) = xml path | } defined class xmlPath scala> new xmlPath(<root><a><b><c/></b></a></root>).b res9: scala.xml.NodeSeq = NodeSeq(<b><c/></b>)
  • 76. SIP-17: Tipo Dynamic  Conversões:  Métodos convencionais:  applyDynamic  Métodos com nome de parâmetros:  applyDynamicNamed  Atribuições (setters):  updateDynamic  Valores (getters):  selectDynamic
  • 77. SIP-18: Modularização de Funcionalidades da Linguagem  Problemas:  Algumas funcionalidades de Scala são de difícil compreensão  Outras induzem a erros  E algumas são experimentais  Mas são todas necessárias, por uma razão ou outra!  Solução: SIP-18
  • 78. SIP-18: Modularização de Funcionalidades da Linguagem  Controla acesso a certas funcionalidades  Uso das funcionalidades causa avisos  Mas podem se tornar erros em futuras versões  Liberação de uso através de:  flag de compilação  valor implícito no escopo  Liberação pode ser herdada  ScalaDoc explica prós e contras de cada funcionalidade
  • 79. SIP-18: Modularização de Funcionalidades da Linguagem  Funcionalidades contenciosas  Operadores pós-fixados  Chamada de métodos implementadas via reflexão  Conversões de tipo implícitas  Higher kinded types  Existenciais  Exceto aqueles que equivalem a Java wildcard types  Tipo Dynamic  Funcionalidades experimentais  Macros
  • 80. SIP-18: Modularização de Funcionalidades da Linguagem // Notação de operador pós-fixado scala> "abc" length warning: there were 1 feature warnings; re-run with -feature for details res0: Int = 3
  • 81. SIP-18: Modularização de Funcionalidades da Linguagem // Notação de operador pós-fixado, com –feature scala> "abc" length <console>:8: warning: postfix operator length should be enabled by making the implicit value language.postfixOps visible. This can be achieved by adding the import clause 'import language.postfixOps' or by setting the compiler option -language:postfixOps. See the Scala docs for value scala.language.postfixOps for a discussion why the feature should be explicitly enabled. "abc" length ^ res0: Int = 3
  • 82. SIP-18: Modularização de Funcionalidades da Linguagem // Chamada de métodos implementadas via reflexão scala> val x = new AnyRef { def hello = println("world") } x: Object{def hello: Unit} = $anon$1@7d628303 scala> x.hello <console>:10: warning: reflective access of structural type member method hello should be enabled by making the implicit value language.reflectiveCalls visible. This can be achieved by adding the import clause 'import language.reflectiveCalls' or by setting the compiler option -language:reflectiveCalls. See the Scala docs for value scala.language.reflectiveCalls for a discussion why the feature should be explicitly enabled. x.hello ^ world
  • 83. SIP-18: Modularização de Funcionalidades da Linguagem // Conversões Implícitas scala> implicit def f(s: String): Int = Predef.augmentString(s).toInt <console>:8: warning: implicit conversion method f should be enabled by making the implicit value language.implicitConversions visible. This can be achieved by adding the import clause 'import language.implicitConversions' or by setting the compiler option -language:implicitConversions. See the Scala docs for value scala.language.implicitConversions for a discussion why the feature should be explicitly enabled. implicit def f(s: String): Int = Predef.augmentString(s).toInt ^ f: (s: String)Int
  • 84. SIP-18: Modularização de Funcionalidades da Linguagem  A funcionalidade limitada são as conversões implícitas  Outros usos de implicits continuam liberados (e incentivados!)  E conversões implícitas através de classes implícitas também
  • 85. SIP-18: Modularização de Funcionalidades da Linguagem // Higher Kinded Types scala> class Monad[M[_]] <console>:9: warning: higher-kinded type should be enabled by making the implicit value language.higherKinds visible. This can be achieved by adding the import clause 'import language.higherKinds' or by setting the compiler option -language:higherKinds. See the Scala docs for value scala.language.higherKinds for a discussion why the feature should be explicitly enabled. class Monad[M[_]] ^ defined class Monad
  • 86. SIP-18: Modularização de Funcionalidades da Linguagem // Existenciais scala> val l: List[ T forSome { type T }] = List(1) <console>:7: warning: the existential type T forSome { type T }, which cannot be expressed by wildcards, should be enabled by making the implicit value language.existentials visible. This can be achieved by adding the import clause 'import language.existentials' or by setting the compiler option -language:existentials. See the Scala docs for value scala.language.existentials for a discussion why the feature should be explicitly enabled. val l: List[ T forSome { type T }] = List(1) ^ l: List[T forSome { type T }] = List(1)
  • 87. SIP-18: Modularização de Funcionalidades da Linguagem // Tipo Dynamic TODO
  • 88. SIP-18: Modularização de Funcionalidades da Linguagem // Macros scala> def g(d: Any): Any = macro f <console>:12: error: macro definition needs to be enabled by making the implicit value language.experimental.macros visible. This can be achieved by adding the import clause 'import language.experimental.macros' or by setting the compiler option -language:experimental.macros. See the Scala docs for value scala.language.experimental.macros for a discussion why the feature needs to be explicitly enabled. def g(d: Any): Any = macro f ^
  • 89. scala.reflect  Permitem explorar a estrutura de um programa,  e interagir com esta estrutura  Wiki: reflexão ocorre em tempo de execução  Scala: você usa a mesma biblioteca em tempo de compilação, com macros  Noções fundamentais:  Bibliotecas de reflexão e Universos  Nomes, símbolos, tipos, árvores  Mirrors
  • 90. scala.reflect – Universos Fonte: Scala Reflection Pre-SIP
  • 91. scala.reflect – Universos  Contém uma série de elementos interligados que, juntos, formam os componentes fundamentais da reflexão  Symbol  Tree  Name  etc...  Uso de path dependent types para associar tipos aos universos dos quais se originaram
  • 92. scala.reflect – Universos  Construído com o “cake pattern” em camadas com diferentes graus de detalhes:  Base:  Conceito fundamentais  Identidade, e pouco mais  JavaUniverse  Manipulação baseada nas facilidades de reflexão provida pela JVM, melhorada com informações de Scala  Makro  Manipulação em tempo de compilação  Universo do compilador, mas com uma API mais restrita  Outros: Compilador
  • 93. scala.reflect – Tipos Fundamentais Name FlagSet Symbol Universo AnnotationInfo Type Position Tree
  • 94. scala.reflect – Name Name TermName TypeName
  • 95. scala.reflect – Name  Scala possui dois espaços de nome:  Tipos  Valores (Term)  Name associa uma string a um desses dois espaços  Name também permite converter entre a representação na linguagem, e a representação nos class files
  • 96. scala.reflect – Symbol Symbol Type owner Name Symbol Type ... Symbol TermName TypeName
  • 97. scala.reflect – Symbol  Todas definições estão associadas a símbolos  Classes  Métodos  Parâmetros  Variáveis  Se você deu um nome, tem um símbolo  Se você não deu um nome, mas chama de “anônimo”, tem um símbolo também  Mutável no compilador, imutável em tempo de execução
  • 98. scala.reflect – Type  Representa a estrutura associada a um tipo:  Membros das classes  Parâmetros e tipo de retorno de um método  etc  Formado por case classes imutáveis  Manipulado através de pattern matching
  • 99. scala.reflect – Tipos e Símbolos scala> import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._ scala> typeOf[List[Int]] res0: reflect.runtime.universe.Type = List[Int] scala> res0.member(newTermName("head")) res1: reflect.runtime.universe.Symbol = method head scala> res1.typeSignature res2: reflect.runtime.universe.Type = => A scala> res1.typeSignatureIn(res0) res3: reflect.runtime.universe.Type = => Int
  • 100. scala.reflect – Tipos e Símbolos def intMethods[T : TypeTag](v: T) = { val IntType = typeOf[Int] val vType = typeOf[T] val methods = vType.nonPrivateMembers.collect { case m: MethodSymbol => m -> m.typeSignatureIn(vType) } methods collect { case (m, mt @ NullaryMethodType(IntType)) => m -> mt case (m, mt @ MethodType(_, IntType)) => m -> mt case (m, mt @ PolyType(_, MethodType(_, IntType))) => m -> mt } }
  • 101. scala.reflect – Tipos e Símbolos def intMethods[T : TypeTag](v: T) = { val IntType = typeOf[Int] val vType = typeOf[T] val methods = vType.nonPrivateMembers.collect { case m: MethodSymbol => m -> m.typeSignatureIn(vType) } methods collect { case (m, mt @ NullaryMethodType(IntType)) => m -> mt case (m, mt @ MethodType(_, IntType)) => m -> mt case (m, mt @ PolyType(_, MethodType(_, IntType))) => m -> mt } }
  • 102. scala.reflect – Tipos e Símbolos // Na verdade, você precisa disso: case (m, mt @ NullaryMethodType(tpe)) if tpe =:= IntType =>
  • 103. scala.reflect – Tree TypTree Tree TermTree children Type Position Symbol Tree Tree ... Tree
  • 104. scala.reflect – Tree  São a representação interna do compilador do código fonte  Imutável, formado por case classes  Essencial ao se lidar com macros  Usado para annotated typed na biblioteca básica
  • 105. scala.reflect – Tree scala> import scala.tools.reflect.ToolBox import scala.tools.reflect.ToolBox scala> import scala.reflect.runtime.{currentMirror => m} import scala.reflect.runtime.{currentMirror=>m} scala> val tb = m.mkToolBox() tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@5bbdee69 scala> val tree = tb.parseExpr("1 to 3 map (_+1)") tree: tb.u.Tree = 1.to(3).map(((x$1) => x$1.$plus(1))) scala> val eval = tb.runExpr(tree) eval: Any = Vector(2, 3, 4)
  • 106. scala.reflect – Tree scala> import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._ scala> showRaw(reify({ def f(x: Int, y: Int) = x + y }).tree) res4: String = Block(List(DefDef(Modifiers(), newTermName("f"), List(), List(List(ValD ef(Modifiers(PARAM), newTermName("x"), Ident(scala.Int), EmptyTree), ValDef(Modifiers( PARAM), newTermName("y"), Ident(scala.Int), EmptyTree))), TypeTree(), Apply(Select(Ide nt(newTermName("x")), newTermName("$plus")), List(Ident(newTermName("y")))))), Literal (Constant(())))
  • 107. scala.reflect – Mirror InstanceMirror ClassMirror MethodMirror ClassMirror FieldMirror MethodMirror ModuleMirror (constructors)
  • 108. scala.reflect – Mirror  Mirrors permitem manipulação de instâncias e classes em tempo de execução  Cada Universe pode ter um ou mais mirrors  Cada mirror está associado a um class loader  Classes de mesmo nome podem existir carregadas por class loaders distintos  Mirrors permitem manipulação baseada na linguagem Scala, e não em sua implementação na JVM
  • 109. scala.reflect – Mirror val obj = "String" val objClass = obj.getClass val classClassLoader = objClass.getClassLoader val classLoaderMirror = runtimeMirror(classClassLoader) val classSymbol = classLoaderMirror.classSymbol(objClass) val classType = classSymbol.typeSignature val methodName = newTermName("length") val methodSymbol = classType.member(methodName).asMethodSymbol val instanceMirror = classLoaderMirror.reflect(obj) val methodMirror = instanceMirror.reflectMethod(methodSymbol) methodMirror.apply() // == (obj.length: Any)
  • 110. Atores e Akka???  A biblioteca padrão deixará de existir  Substituída pelo Akka  Quando???  A biblioteca Akka fará parte da distribuição 2.10  Somente binários – código fonte permanece separado  Será disponibilizado um guia de migração  A biblioteca padrão virá com um “kit” para facilitar a migração  Para que serve?
  • 112. Especulações  untyped macros  for { val x = 0; x < 10; x += 1 } println(x)  macro types  class X extends MacroClassY(parm)  macro annotations  @memoize def fat(n: Int) = if (n > 0) n * fat(n -1) else 1  effect system  integração de abstract types e type parameters.  pré-processador (DOA!)