Scala: unindo programação funcional e orientação a objetos
-
Upload
felipe-hummel -
Category
Technology
-
view
197 -
download
0
Transcript of Scala: unindo programação funcional e orientação a objetos
Scala Unindo programação funcional
e orientação a objetos
Felipe Hummel
Quem?• Graduação (2008) e Mestrado (2011) pela UFAM
• NewsMonitor
• Desde 2012, morando em São Paulo nos últimos 2 anos
• Site profissional para monitoramento de notícias em tempo real
• 170M de notícias
• 5M/mês
• ~30K linhas de código Scala (2 Devs back-end)
• Maiores desafios estão na coleta, processamento e busca de notícias
Scala, o quê?• Relativamente “nova" (2004) começando a ganhar tração
depois de 2010
• Linguagem com tipagem forte e estática (“mais" do que outras)
• “Multiparadigma”: funcional + OO
• Open Source
• Compila para bytecode da JVM (Java Virtual Machine)
• Facilmente interoperável com código e libs Java
Scala, quem usa?
Scala, quem usa?
Scala, por quê?• Consegue ser roazavelmente familiar mas ainda introduz conceitos
funcionais que mudam a forma como programamos
• Concisão de código sem perca de legibilidade
• Inferência de tipos (local, diferente de Haskell/ML)
• Coleções muito ricas em funcionalidades
• 90% da rotina é lidar com coleções de objetos
• Preferência por imutabilidade
• Quase tudo faz parte da biblioteca e não é sintaxe especial da linguagem
• Poder para expressar muita coisa
Scala
sudo apt-get install scala
Val e Var
val soma = 1 + 1
Val e Var
val soma = 1 + 1 soma = 10 //error: reassignment to val
Val e Var
var soma = 1 + 1
Val e Var
var soma = 1 + 1 soma = soma + 1 //OK!
Inferência de tipos
val soma = 1 + 1
Inferência de tipos
val soma: Int = 1 + 1 soma.substring(0) //error: value substring is not a member of Int
Inferência de tipos
val soma = 1 + 1 soma.substring(0) //error: value substring is not a member of Int
Inferência de tipos
val soma: Int = 1 + 1 val nome: String = “teste" val lista: List[String] = List(“teste”)
Inferência de tipos
val soma = 1 + 1 val nome = “teste" val lista = List(“teste”)
Funções
def add1(n: Int) = n + 1 // ^ inferência de tipo de retorno
Funções
def add1(n: Int): Int = n + 1 // ^ tipo de retorno explícito
Funções
def add1(n: Int): Int = { println(“adicionando 1”) n + 1 // última expressão: retorno automático }
Funções anônimas
val f = (n: Int) => n + 1 // ^ inferindo tipo de retorno f(1) // retorna 2 val g: (Int => Int) = n => n * 2 val h: (Int => Int) = _ * 2
Funções anônimas
val f = (n: Int) => n + 1 val g: (Int => Int) = n => n * 2 val fg = f.andThen(g) fg(10) // retorna 22
Lazy vals
lazy val usuários = todosUsuarios() // todosUsuarios() ainda não foi chamada!! val result = usuarios // todosUsuarios() foi chamada agora println(usuarios)// não precisou recomputar
Classes
class Curso(id: Int, nome: String) class Aluno(id: Int, curso: Curso, idade: Int)
Classes
// ISSO NÃO É SCALA CORRETO! class Curso { private val id: Int private val nome: String def constructor(_id: Int, _nome: String) { id = _id nome = _nome } }
Classes
// ISSO É SCALA CORRETO! class Curso(id: Int, nome: String)
Classes
class Curso(id: Int, nome: String) val computacao = new Curso(1,“Computação”) println(computacao.nome) //error: value nome is not a member of Curso // nome não é acessível publicamente
Classes
class Curso(val id: Int, val nome: String) val computacao = new Curso(1,“Computação”) println(computacao.nome) // Computação
Classes
class Curso(id: Int, nome: String) { def comoString(): String = s”Curso($id, $nome)“ } val computacao = new Curso(1,“Computação”) println(computacao.comoString()) // Curso(1, Computação)
case classes
case class Curso(id: Int, nome: String) val computacao = Curso(1,“Computação”) println(computacao) // Curso(1, Computação)
case classes// implementa pra mim: // - toString() bonitinho // - equals() e hashCode() // - atributos são públicos e imutáveis por padrão // - não precisa do new para instanciar objeto case class Curso(id: Int, nome: String) val computacao = Curso(1,“Computação”) println(computacao) // Curso(1, Computação)
public class Person { private final String firstName; private final String lastName;
String getFirstName() { return firstName; } String getLastName() { return lastName; } public Person(String first, String last) { this.firstName = first; this.lastName = last; } public int hashCode() { return goodHashCode(firstName, lastName); } public boolean equals(Object o) { if ( this == aThat ) return true; if ( !(aThat instanceof Person) ) return false; Person that = (Person)aThat; return EqualsUtil.areEqual(this.firstName, that.firstName) & EqualsUtil.areEqual(this.lastName, that.lastName); } }
case class Person(firstName: String, lastName: String)
objects// um "singleton" object ContadorGlobal { var contador = 0 def incrementaERetorna() = { contador += 1 contador } }
// apesar do exemplo, por favor não criem vars globais :)ContadorGlobal.incrementaERetorna() // 1 ContadorGlobal.incrementaERetorna() // 2 ContadorGlobal.incrementaERetorna() // 3
parâmetros de tipo (generics)
val cursos: List[String] = List(“Computação”, “Matemática”, "Física") val cursosPorNome: Map[String, Int] = Map("Computação" -> 1234, "Matemática" -> 423, "Física" -> 5322, "Biologia" -> 1312)
Coleções!
Mão na massa
Scala é isso
80% de Scala é isso
Scala mudou a forma
como programamos
Parar de acessar o que não está lá
• NullPointerException (Java)
• Segmentation Fault (C/C++)
• undefined is not a function (Javascript)
• AttributeError: 'NoneType' object has no attribute (Python)
• Call to a member function on a non-object (PHP)
Parar de acessar o que não está lá
• NullPointerException (Java)
• undefined is not a function (Javascript)
• AttributeError: 'NoneType' object has no attribute (Python)
• Call to a member function on a non-object (PHP)
Null Pointer Exc… NÃO
• NullPointerException (Java)
• undefined is not a function (Javascript)
• AttributeError: 'NoneType' object has no attribute (Python)
• Call to a member function on a non-object (PHP)
SCALA
NÃO TEM
!!!!!!!!!
Null Pointer Exc… NÃO
• Uso de Option[MeuTipo] quando necessário
Tipagem Estática!• Linguagens com tipagem estáticas pegaram fama de serem
verbosas
• Não necessariamente
• Scala consegue ser tão concisa quanto as linguagens dinâmicas
• Tendência de adicionar tipos opcionais nas linguagens dinâmicas
• Javascript, PHP, Python
• Difícil viver sem um compilador me ajudando
Imutabilidade
• Coisas a menos pra guardar na sua cabeça
• Não me preocupo se alguém pode ou vai mudar meu objeto
• Você pode passar objetos imutáveis pra lá e pra cá de boa
• Thread-safe por padrão
Scala é a melhor coisa do mundo?
Scala é a melhor coisa do mundo?
A minha linguagem/framework/biblioteca
não é a melhor possível
Mais conciso e expressivo que Scala é impossível
Mais conciso e expressivo que Haskell é impossível
Programação é sempre um comando seguido do outro
Programação pode ser só (funções (chamando (funções ‘!’)))
em Clojure
Ou damos free() na mão ou usamos Garbage Collector
Ou damos free() na mão ou usamos Garbage Collector
ou usamos Rust e o seu sistema de ownership
Sempre dá pra melhorar