Migrando	
  pra	
  Scala	
  


     Maurício	
  Linhares	
  
       @mauriciojr	
  
    h5p://techbot.me/	
  
h5p://www.officedrop.com/	
  	
  
MEU	
  PROBLEMA?	
  
Migrar	
  uma	
  plataforma	
  de	
  
     Ruby	
  para	
  Java	
  
DEPOIS	
  DE	
  ALGUNS	
  ANOS	
  DE	
  RUBY	
  
VOLTAR	
  A	
  PROGRAMAR	
  EM	
  JAVA	
  
FOI…	
  
JavaScript	
            Python	
  

  O	
  Java	
  envelheceu	
  e	
  a	
  
concorrência	
  andou	
  rápido	
  

 C#	
          Ruby	
  

                       Erlang	
  
•  Closures	
  
 •  Closures	
  
 •  Closures	
  
 •  Closures	
  
•  E	
  coleções	
  
Vá	
  devagar	
  

Que	
  devagar	
  chega	
  também	
  
Closures	
  são	
  importantes	
  
        mesmo?	
  
       Show	
  me	
  the	
  code!	
  
Implementar	
  uma	
  solução	
  que	
  deve	
  
tentar	
  várias	
  vezes	
  executar	
  uma	
  
tarefa	
  se	
  ela	
  falhar.	
  Pense	
  em	
  
chamadas	
  de	
  rede.	
  
CASO?	
  
Classes?	
  
	
  
•  RetryableService	
  para	
  casos	
  que	
  não	
  retornam	
  



•  ReturningRetryableService	
  para	
  casos	
  que	
  
   retornam	
  alguma	
  coisa	
  
Usando	
  
new	
  RetryableService()	
  {	
  
	
  	
  @Override	
  
	
  	
  public	
  void	
  call()	
  throws	
  ExcepYon	
  {	
  
	
  	
  	
  	
  System.out.println("Estou	
  dentro	
  da	
  
chamada!");	
  
	
  	
  }	
  
};	
  
Usando	
  com	
  return	
  
	
  @Test	
  
public	
  void	
  testRetryWithResult()	
  {	
  
	
  
	
  	
  String	
  result	
  =	
  new	
  ReturningRetryableService<String>(){	
  
	
  
	
  	
  	
  	
  @Override	
  
	
  	
  	
  	
  public	
  String	
  call()	
  throws	
  ExcepYon	
  {	
  
	
  	
  	
  	
  	
  	
  String	
  conteudo	
  =	
  "olá	
  mundo!”;	
  
	
  	
  	
  	
  	
  	
  return	
  conteudo;	
  
	
  	
  	
  	
  }	
  
	
  	
  }.getResult();	
  
	
  
	
  	
  System.out.println(result);	
  
}	
  
Implementação	
  em	
  Scala	
  
def	
  retry[T](n:	
  Int)(fn:	
  =>	
  T):	
  T	
  =	
  {	
  
      	
  try	
  {	
  
      	
   	
  fn()	
  
      	
  }	
  catch	
  {	
  
      	
   	
  case	
  e	
  =>	
  
      	
   	
   	
  if	
  (n	
  >	
  1)	
  {	
  
      	
   	
   	
   	
  retry(n	
  -­‐	
  1)(fn)	
  
      	
   	
   	
  }	
  
      	
   	
   	
  else	
  throw	
  new	
  IllegalStateExcepYon(e)	
  
      	
  }	
  
}	
  
Uso	
  em	
  Scala	
  
	
  
retry	
  {	
  
	
  	
  	
  	
  storeNote(document)	
  
}	
  
E	
  as	
  coleções?	
  

Show	
  me	
  the	
  code	
  [2]	
  
Em	
  Java	
  
	
  	
  	
  	
  @Test	
  
	
  	
  	
  	
  public	
  void	
  testForeach()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  for	
  (	
  Cidade	
  cidade	
  :	
  Cidade.CIDADES	
  )	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  System.out.println(cidade.getNome());	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
Em	
  Scala	
  
                	
  	
  
	
  	
  	
  	
  @Test	
  
                	
  def	
  testForeach	
  {	
  
                	
   	
  Cidade.CIDADES.foreach	
  {cidade	
  =>	
  
println(cidade.getNome)}	
  
                	
  }	
  
Em	
  Java	
  
@Test	
  
public	
  void	
  testSomar()	
  {	
  
	
  	
  BigInteger	
  resultado	
  =	
  BigInteger.ZERO;	
  
	
  
	
  	
  for	
  (	
  Cidade	
  cidade	
  :	
  Cidade.CIDADES)	
  {	
  
	
  	
  	
  	
  resultado	
  =	
  
resultado.add(	
  BigInteger.valueOf(cidade.getPopulacao())	
  );	
  
	
  	
  }	
  
	
  
	
  	
  System.out.println(	
  resultado	
  );	
  
}	
  
Em	
  Scala	
  
@Test	
  
def	
  testSoma	
  {	
  
	
  
	
  	
  val	
  resultado	
  =	
  cidades.foldLeo(BigInt(0))	
  {	
  (soma,	
  
cidade)	
  =>	
  soma	
  +	
  cidade.getPopulacao	
  }	
  
	
  	
  	
  
	
  	
  println(resultado)	
  
}	
  
Em	
  Java	
  
	
  @Test	
  
public	
  void	
  testTransformar()	
  {	
  
	
  	
  List<Long>	
  populacoes	
  =	
  new	
  ArrayList<Long>();	
  
	
  	
  for	
  (	
  Cidade	
  cidade	
  :	
  Cidade.CIDADES	
  )	
  {	
  
	
  	
  	
  	
  populacoes.add(	
  cidade.getPopulacao()	
  );	
  
	
  	
  }	
  
	
  	
  System.out.println(	
  populacoes	
  );	
  
}	
  
Em	
  Scala	
  
@Test	
  
def	
  testMap	
  {	
  
	
  	
  val	
  populacoes	
  =	
  Cidade.CIDADES.map	
  {	
  cidade	
  
=>	
  cidade.getPopulacao	
  }	
  
	
  	
  println(	
  populacoes	
  )	
  
}	
  
Em	
  Java	
  
Cidade	
  resultado	
  =	
  null;	
  
	
  
for	
  (Cidade	
  cidade	
  :	
  Cidade.CIDADES)	
  {	
  
	
  	
  if	
  (cidade.getPopulacao()	
  ==	
  100)	
  {	
  
	
  	
  	
  	
  resultado	
  =	
  cidade;	
  
	
  	
  	
  	
  break;	
  
	
  	
  }	
  
}	
  
	
  
if	
  (	
  resultado	
  !=	
  null	
  )	
  {	
  
	
  	
  System.out.println(	
  resultado	
  );	
  
}	
  else	
  {	
  
	
  	
  System.out.println(	
  "Não	
  há	
  cidade	
  com	
  essa	
  população"	
  );	
  
}	
  
Em	
  Scala	
  
@Test	
  
def	
  testEncontrarCidadePeloNome	
  {	
  
	
  
	
  	
  val	
  result	
  =	
  Cidade.CIDADES.find	
  {	
  cidade	
  =>	
  
cidade.getPopulacao	
  >	
  10000000	
  }	
  
	
  
	
  	
  result	
  match	
  {	
  
	
  	
  	
  	
  case	
  Some(cidade)	
  =>	
  println(	
  cidade.getNome	
  )	
  
	
  	
  	
  	
  case	
  None	
  =>	
  println(	
  "Não	
  há	
  cidade	
  com	
  os	
  dados	
  
passados"	
  )	
  
	
  	
  }	
  
}	
  
Adendo	
  -­‐	
  Prefira	
  iterações	
  
            internas	
  
       Coleções	
  paralelas	
  
  Gerenciamento	
  automáYco	
  de	
  
            recursos	
  
Mas	
  outras	
  linguagens	
  fazem	
  
          isso	
  também	
  
       Por	
  que	
  escolher	
  Scala?	
  
Preferência	
  pelo	
  mundo	
  final	
  e	
  
           imutável	
  
    Não	
  comparYlhe	
  nada	
  e	
  seja	
  feliz	
  
       num	
  mundo	
  concorrente	
  
Raiz	
  forte	
  no	
  mundo	
  da	
  
  programação	
  funcional	
  
Só	
  tenha	
  cuidado	
  ao	
  olhar	
  o	
  código	
  
                fonte	
  do	
  ScalaZ	
  
Compawvel	
  com	
  o	
  seu	
  legado	
  
              Java	
  
   E	
  código	
  Scala	
  PODE	
  ser	
  chamado	
  
                  através	
  do	
  Java	
  
Biblioteca	
  base	
  madura	
  

 Poucas	
  mudanças	
  drásYcas	
  tem	
  
acontecido	
  na	
  biblioteca	
  padrão	
  da	
  
               linguagem	
  
Ferramentas	
  em	
  situação	
  
       aceitável	
  
Ao	
  menos	
  pra	
  uma	
  linguagem	
  que	
  
 está	
  chamando	
  atenção	
  agora	
  
Actors	
  and	
  Akka	
  

The	
  Killer	
  App	
  for	
  concurrency	
  and	
  
          parallel	
  programming	
  
Cuidado	
  com	
  features	
  que	
  você	
  
  não	
  entende	
  por	
  completo	
  
      Se	
  não	
  sabe	
  brincar,	
  não	
  vá	
  pro	
  
                      brinquedo	
  
Cuidado	
  com	
  as	
  coleções,	
  elas	
  
podem	
  não	
  ser	
  o	
  que	
  você	
  pensa	
  
          scala.immutable.List	
  não	
  é	
  
          equivalente	
  ao	
  java.uYl.List	
  	
  
match/case	
  não	
  é	
  igual	
  ao	
  
      switch/case	
  
O	
  custo	
  de	
  execução	
  pode	
  ser	
  muito	
  
                      diferente	
  
Evite	
  usar	
  símbolos	
  ou	
  caracteres	
  
         unicode	
  no	
  seu	
  código	
  
Scala	
  não	
  serve	
  pra	
  fazer	
  CRUD	
  
                   web	
  
       Pra	
  isso	
  você	
  usa	
  Ruby	
  e	
  Rails	
  
Isto	
  não	
  é	
  Scala!	
  
Adicione	
  mais	
  uma	
  ferramenta	
  
  no	
  seu	
  toolbox	
  e	
  seja	
  feliz	
  
    Isto	
  não	
  vai	
  resolver	
  todos	
  os	
  seus	
  
                        problemas	
  
Migrando pra Scala

Migrando pra Scala

  • 1.
    Migrando  pra  Scala   Maurício  Linhares   @mauriciojr   h5p://techbot.me/   h5p://www.officedrop.com/    
  • 2.
    MEU  PROBLEMA?   Migrar  uma  plataforma  de   Ruby  para  Java  
  • 3.
    DEPOIS  DE  ALGUNS  ANOS  DE  RUBY   VOLTAR  A  PROGRAMAR  EM  JAVA   FOI…  
  • 5.
    JavaScript   Python   O  Java  envelheceu  e  a   concorrência  andou  rápido   C#   Ruby   Erlang  
  • 6.
    •  Closures   •  Closures   •  Closures   •  Closures   •  E  coleções  
  • 7.
    Vá  devagar   Que  devagar  chega  também  
  • 8.
    Closures  são  importantes   mesmo?   Show  me  the  code!  
  • 9.
    Implementar  uma  solução  que  deve   tentar  várias  vezes  executar  uma   tarefa  se  ela  falhar.  Pense  em   chamadas  de  rede.   CASO?  
  • 10.
    Classes?     • RetryableService  para  casos  que  não  retornam   •  ReturningRetryableService  para  casos  que   retornam  alguma  coisa  
  • 11.
    Usando   new  RetryableService()  {      @Override      public  void  call()  throws  ExcepYon  {          System.out.println("Estou  dentro  da   chamada!");      }   };  
  • 12.
    Usando  com  return    @Test   public  void  testRetryWithResult()  {        String  result  =  new  ReturningRetryableService<String>(){            @Override          public  String  call()  throws  ExcepYon  {              String  conteudo  =  "olá  mundo!”;              return  conteudo;          }      }.getResult();        System.out.println(result);   }  
  • 13.
    Implementação  em  Scala   def  retry[T](n:  Int)(fn:  =>  T):  T  =  {    try  {      fn()    }  catch  {      case  e  =>        if  (n  >  1)  {          retry(n  -­‐  1)(fn)        }        else  throw  new  IllegalStateExcepYon(e)    }   }  
  • 14.
    Uso  em  Scala     retry  {          storeNote(document)   }  
  • 15.
    E  as  coleções?   Show  me  the  code  [2]  
  • 16.
    Em  Java          @Test          public  void  testForeach()  {                  for  (  Cidade  cidade  :  Cidade.CIDADES  )  {                          System.out.println(cidade.getNome());                  }          }  
  • 17.
    Em  Scala              @Test    def  testForeach  {      Cidade.CIDADES.foreach  {cidade  =>   println(cidade.getNome)}    }  
  • 18.
    Em  Java   @Test   public  void  testSomar()  {      BigInteger  resultado  =  BigInteger.ZERO;        for  (  Cidade  cidade  :  Cidade.CIDADES)  {          resultado  =   resultado.add(  BigInteger.valueOf(cidade.getPopulacao())  );      }        System.out.println(  resultado  );   }  
  • 19.
    Em  Scala   @Test   def  testSoma  {        val  resultado  =  cidades.foldLeo(BigInt(0))  {  (soma,   cidade)  =>  soma  +  cidade.getPopulacao  }            println(resultado)   }  
  • 20.
    Em  Java    @Test   public  void  testTransformar()  {      List<Long>  populacoes  =  new  ArrayList<Long>();      for  (  Cidade  cidade  :  Cidade.CIDADES  )  {          populacoes.add(  cidade.getPopulacao()  );      }      System.out.println(  populacoes  );   }  
  • 21.
    Em  Scala   @Test   def  testMap  {      val  populacoes  =  Cidade.CIDADES.map  {  cidade   =>  cidade.getPopulacao  }      println(  populacoes  )   }  
  • 22.
    Em  Java   Cidade  resultado  =  null;     for  (Cidade  cidade  :  Cidade.CIDADES)  {      if  (cidade.getPopulacao()  ==  100)  {          resultado  =  cidade;          break;      }   }     if  (  resultado  !=  null  )  {      System.out.println(  resultado  );   }  else  {      System.out.println(  "Não  há  cidade  com  essa  população"  );   }  
  • 23.
    Em  Scala   @Test   def  testEncontrarCidadePeloNome  {        val  result  =  Cidade.CIDADES.find  {  cidade  =>   cidade.getPopulacao  >  10000000  }        result  match  {          case  Some(cidade)  =>  println(  cidade.getNome  )          case  None  =>  println(  "Não  há  cidade  com  os  dados   passados"  )      }   }  
  • 24.
    Adendo  -­‐  Prefira  iterações   internas   Coleções  paralelas   Gerenciamento  automáYco  de   recursos  
  • 25.
    Mas  outras  linguagens  fazem   isso  também   Por  que  escolher  Scala?  
  • 26.
    Preferência  pelo  mundo  final  e   imutável   Não  comparYlhe  nada  e  seja  feliz   num  mundo  concorrente  
  • 27.
    Raiz  forte  no  mundo  da   programação  funcional   Só  tenha  cuidado  ao  olhar  o  código   fonte  do  ScalaZ  
  • 28.
    Compawvel  com  o  seu  legado   Java   E  código  Scala  PODE  ser  chamado   através  do  Java  
  • 29.
    Biblioteca  base  madura   Poucas  mudanças  drásYcas  tem   acontecido  na  biblioteca  padrão  da   linguagem  
  • 30.
    Ferramentas  em  situação   aceitável   Ao  menos  pra  uma  linguagem  que   está  chamando  atenção  agora  
  • 31.
    Actors  and  Akka   The  Killer  App  for  concurrency  and   parallel  programming  
  • 33.
    Cuidado  com  features  que  você   não  entende  por  completo   Se  não  sabe  brincar,  não  vá  pro   brinquedo  
  • 34.
    Cuidado  com  as  coleções,  elas   podem  não  ser  o  que  você  pensa   scala.immutable.List  não  é   equivalente  ao  java.uYl.List    
  • 35.
    match/case  não  é  igual  ao   switch/case   O  custo  de  execução  pode  ser  muito   diferente  
  • 36.
    Evite  usar  símbolos  ou  caracteres   unicode  no  seu  código  
  • 37.
    Scala  não  serve  pra  fazer  CRUD   web   Pra  isso  você  usa  Ruby  e  Rails  
  • 38.
    Isto  não  é  Scala!  
  • 39.
    Adicione  mais  uma  ferramenta   no  seu  toolbox  e  seja  feliz   Isto  não  vai  resolver  todos  os  seus   problemas