scala: unindo programação funcional e orientação a objetos

Post on 13-Apr-2017

197 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

Obrigado! Dúvidas?

@felipehummel felipehummel@gmail.com

top related