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
em ponto scala> 077 <console>:1: warning: Treating numbers with a leading zero as octal is deprecated. 077 ^ res10: Int = 63 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
 Método  Pacotes for ( val i <- 1 to 10) println(i) scala.collection.mutable.CloneableCollection scala.collection.immutable.Queue.+ scala.testing.SUnit
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
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.
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...
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???
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
mutable.ParArray(1, 2, 3) pc.tasksupport = new ForkJoinTaskSupport( new scala.concurrent.ForkJoinPool(2)) pc map { _ + 1) pc.tasksupport = new ThreadPoolTaskSupport()
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
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?
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!
Library”) extremamente popular  Mas cerimonioso...  “Extension methods” se tornando comuns em outras linguagens  E com menos cerimônia!  Solução: implicit class
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: 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() } }
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.
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
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!
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
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!
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
 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
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...
| 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>)
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
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
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
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
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
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
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
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
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)
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 ^
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
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
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
 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
 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
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
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
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)
 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?
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!)