Slide 1

Slide 1 text

De onde viemos e para onde vamos? Daniel Capó Sobral

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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.

Slide 5

Slide 5 text

Sumário  Histórico  Futuro Imediato  Versionamento  Processo de Release  Bug fixes  Melhorias  SIPs (Scala Improvement Process)  Reflection  Atores e Akka  Futuro Distante

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Histórico • 2.9.2 2012 • 2.9.0 • 2.9.1 • 2.8.2 2011 • 2.8.0 • 2.8.1 2010 • 2.7.3 • 2.7.4 • 2.7.5 • 2.7.6 • 2.7.7 2009 • 2.7.1 • 2.7.2 2008 • 2.3.2 • 2.3.3 • 2.4.0 • 2.5.0 • 2.5.1 • 2.6.0 • 2.6.1 2007 • 2.0.0 • 2.1.0 • 2.1.1 • 2.1.2 • 2.1.3 • 2.1.5 • 2.1.6 • 2.1.7 • 2.1.8 • 2.2.0 • 2.3.0 • 2.3.1 2006 • 1.4.0 2005 • 1.0.0 • 1.1.0 • 1.1.0 • 1.1.1 • 1.2.0 • 1.3.0 2004 • 0.8.1 • 0.8.2 • 0.9.0 • 0.9.1 2003

Slide 8

Slide 8 text

Alguns marcos importantes 2006 • Scalac escrito em Scala • Implicits • Traits e linearização • Multilline Strings 2007 • Extractors • Private/protected primary constructors • Private[this] • Placeholder parameters • Early Initialization • Abstract Type Constructors • Existential Types • Lazy values • Structural Types 2008 • Java Generics • Case Class Extractors 2010 • Novo design de Collections • Compatibilidade Binária 2011 • Parallel Collections

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Explicando Versionamento 2 Epoch .9 Major .1 Minor -1 Bug fix

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

Exemplos de Novas Depreciações  Números octais!  Double terminando em ponto scala> 077 :1: warning: Treating numbers with a leading zero as octal is deprecated. 077 ^ res10: Int = 63 scala> 1. :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

Slide 13

Slide 13 text

Exemplos de Depreciações Removidas  Características de linguagem  Classe  Método  Pacotes for ( val i <- 1 to 10) println(i) scala.collection.mutable.CloneableCollection scala.collection.immutable.Queue.+ scala.testing.SUnit

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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.

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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?

Slide 19

Slide 19 text

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)

Slide 20

Slide 20 text

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]  ???

Slide 21

Slide 21 text

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...

Slide 22

Slide 22 text

scala.util.Try def percentCompleted(total: Int, done: Int): Int = Try ( done * 100 / total ) getOrElse 100

Slide 23

Slide 23 text

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 }

Slide 24

Slide 24 text

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)

Slide 25

Slide 25 text

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???

Slide 26

Slide 26 text

 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

Slide 27

Slide 27 text

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))

Slide 28

Slide 28 text

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()

Slide 29

Slide 29 text

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 = ??? }

Slide 30

Slide 30 text

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)

Slide 31

Slide 31 text

???  ??? é 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!

Slide 32

Slide 32 text

??? 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/

Slide 33

Slide 33 text

??? 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/

Slide 34

Slide 34 text

Melhorias  Scaladoc  Implicits!  Diagramas!  API docs

Slide 35

Slide 35 text

ScalaDoc & Implicits

Slide 36

Slide 36 text

Parallel Collections Docs!

Slide 37

Slide 37 text

Diagramas de Classe!

Slide 38

Slide 38 text

Parâmetros para ScalaDoc  -implicits  -diagrams  Esse slide foi exigência de Vlad Ureche ;-)

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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)

Slide 41

Slide 41 text

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?

Slide 42

Slide 42 text

SIP-11: String Interpolation def hello(name: String = "world"): String = "Hello, " + name + "! " // Interpolation! def hello(name: String = "world"): String = s"Hello, $name! "

Slide 43

Slide 43 text

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"

Slide 44

Slide 44 text

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)

Slide 45

Slide 45 text

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!

Slide 46

Slide 46 text

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$arg\\E$part" } mkString "" (sc.parts.head + res).r } } implicit def toRC(sc: StringContext) = new RegexContext(sc)

Slide 47

Slide 47 text

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$arg\\E$part" } mkString "" }".r } } implicit def toRC(sc: StringContext) = new RegexContext(sc)

Slide 48

Slide 48 text

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!

Slide 49

Slide 49 text

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"

Slide 50

Slide 50 text

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$p\\E") val r = (partsr mkString "(.*)").r s match { case r(xs @ _*) => Some(xs) case _ => None } } } }

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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 } }

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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) }

Slide 55

Slide 55 text

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) }

Slide 56

Slide 56 text

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) }

Slide 57

Slide 57 text

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() } }

Slide 58

Slide 58 text

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.

Slide 59

Slide 59 text

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 } }

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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!

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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.

Slide 66

Slide 66 text

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”

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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!

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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))) } }

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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...

Slide 75

Slide 75 text

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().b res9: scala.xml.NodeSeq = NodeSeq()

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

 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

Slide 78

Slide 78 text

 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

Slide 79

Slide 79 text

 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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

SIP-18: Modularização de Funcionalidades da Linguagem // Notação de operador pós-fixado, com –feature scala> "abc" length :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

Slide 82

Slide 82 text

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 :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

Slide 83

Slide 83 text

SIP-18: Modularização de Funcionalidades da Linguagem // Conversões Implícitas scala> implicit def f(s: String): Int = Predef.augmentString(s).toInt :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

Slide 84

Slide 84 text

 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

Slide 85

Slide 85 text

SIP-18: Modularização de Funcionalidades da Linguagem // Higher Kinded Types scala> class Monad[M[_]] :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

Slide 86

Slide 86 text

SIP-18: Modularização de Funcionalidades da Linguagem // Existenciais scala> val l: List[ T forSome { type T }] = List(1) :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)

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

SIP-18: Modularização de Funcionalidades da Linguagem // Macros scala> def g(d: Any): Any = macro f :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 ^

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

scala.reflect – Universos Fonte: Scala Reflection Pre-SIP

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

scala.reflect – Tipos Fundamentais Universo Name Symbol Type Tree Position AnnotationInfo FlagSet

Slide 94

Slide 94 text

scala.reflect – Name Name TermName TypeName

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

scala.reflect – Symbol Symbol Type Symbol Type ... owner Symbol Name TermName TypeName

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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 } }

Slide 101

Slide 101 text

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 } }

Slide 102

Slide 102 text

scala.reflect – Tipos e Símbolos // Na verdade, você precisa disso: case (m, mt @ NullaryMethodType(tpe)) if tpe =:= IntType =>

Slide 103

Slide 103 text

scala.reflect – Tree Tree children Tree Tree ... Tree Type Position Symbol TypTree TermTree

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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)

Slide 106

Slide 106 text

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(())))

Slide 107

Slide 107 text

scala.reflect – Mirror InstanceMirror ClassMirror FieldMirror MethodMirror ModuleMirror ClassMirror MethodMirror (constructors)

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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)

Slide 110

Slide 110 text

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?

Slide 111

Slide 111 text

No content

Slide 112

Slide 112 text

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!)