Um site muito bacana para buscar código fonte, soluções etc para várias linguagens:
http://refactormycode.com/codes/recent/python
Alias, muitas das minhas buscas no google por soluções, bugs etc acabam caindo no site StackOverflow. Também é um ótimo site: http://stackoverflow.com
Mostrando postagens com marcador scala. Mostrar todas as postagens
Mostrando postagens com marcador scala. Mostrar todas as postagens
quinta-feira, 9 de setembro de 2010
sábado, 28 de agosto de 2010
Design Patterns em Scala: Command
Command:
Command.scala
package scala.behavioral
import scala.collection.jcl.ArrayList
// Generic/Abstract objects
trait Command[V] {
val parameters = new ArrayList[Any]()
// throw an exception if invalid parameters
def validate() {}
def execute() : V
def addParameters(params:Any*) {
this.parameters ++ params
}
}
trait SimpleCommand extends Command[Any] {
def execute() : Any
}
// Composite
trait CompoundCommand[V] extends Command[ArrayList[V]] {
val commands = new ArrayList[Command[V]]()
override def validate() {
for(command <- commands)
command.validate()
}
override def execute() : ArrayList[V] = {
var result = new ArrayList[V]()
for(command <- commands)
result.add(command.execute())
return result
}
}
trait SimpleCompoundCommand extends CompoundCommand[Any]
// Concrete objects
case class MyValue(val str:String)
class SomeConcreteCommand extends Command[MyValue] {
override def execute() : MyValue = {
print("Hello ")
return new MyValue("SomeConcreteCommand")
}
}
class AnotherConcreteCommand extends Command[MyValue] {
override def execute() : MyValue = {
println("Command!")
return new MyValue("AnotherConcreteCommand")
}
}
class ComplexConcreteCommand extends CompoundCommand[MyValue] {
commands.add(new SomeConcreteCommand())
commands.add(new AnotherConcreteCommand())
}
object CommandClient extends Application {
var c1 = new SomeConcreteCommand()
var c2 = new AnotherConcreteCommand()
var c3 = new ComplexConcreteCommand()
c1.execute()
c2.execute()
c3.execute()
}
Design Patterns em Scala: Singleton
Singleton:
Em Scala o padrão Singleton está embutido na linguagem e substitui os temíveis métodos static de Java que são um pesadelo para testes de unidade. O Singleton, criado com a palavra reservada object agrega os métodos de classe, isto é, que não depende dos dados de uma instância. Veja o exemplo abaixo:
Singleton.scala
package scala.creational
// Permitir a criação de uma só instância de um tipo de objeto
object Singleton {
// object in scala is a singleton class
var value:Int = _
def someMethod() : String = {
"Hello Singleton!"
}
}
// Error:
//class BadSingleton private () {
// private var instance:BadSingleton = null
//
// def getInstance() : BadSingleton = {
// if(instance == null) instance = new DummySingleton()
// return instance
// }
//}
// Client
object SingletonClient extends Application {
println(Singleton.someMethod())
// Compile error
// var s = new Singleton()
var s1 = Singleton
var s2 = Singleton
println(Singleton.value)
s1.value = 1
println(Singleton.value)
s2.value = 2
println(Singleton.value)
println(s1 == s2)
// Compile error
// println(new BadSingleton().getInstance())
// println(BadSingleton.getInstance())
}
Design Patterns em Scala: Composite
Composite:
Composite.scala
package scala.structural
import scala.collection.jcl.ArrayList
// Permite tratar uma requisição a uma composição de componentes da mesma forma a um único componente
class SomeObject {
def someTask() {}
}
class Composite extends SomeObject {
var objects = new ArrayList[SomeObject]()
override def someTask() {
for(o <- objects)
o.someTask()
}
}
// Client
object CompositeClient extends Application {
var someObject1 = new SomeObject()
var someObject2 = new Composite()
someObject1.someTask()
someObject2.someTask()
}
Design Patterns em Scala: Template Method
O padrão TemplateMethod é muito legal, essencial principalmente para quando vamos implementar frameworks ou engines. Vale a pena conhecer também! Segue o arquivo:
TemplateMethod.scala
TemplateMethod.scala
package scala.behavioral
// Define o esqueleto de um algoritmo e delega a implementação de alguns passos às sub-classes
// Abstract Implementation
abstract class SomeFramework {
def templateMethod() {
// some implementation here
someAbstractMethod()
// some implementation here
}
def someAbstractMethod()
}
// Concrete Implementation
class MyFramework extends ClassWithTemplateMethod {
override def someAbstractMethod() {
println("partial implementation of the framework")
}
}
// Client
object TemplateMethodClient extends Application {
var framework = new MyFramework()
framework.templateMethod()
}
Google App Engine (GAE)
O Google App Engine (GAE) é um conjunto de ferramentas de desenvolvimento e administraçao que permite rodar aplicações Web em cima da plataforma do Google, isto é, na plataforma mais escalável do mundo. O serviço é gratuíto mas possui cotas diária de uso de disco, processamento, memória, banco de dados, etc. Para quem precisar de mais, daí então existem planos pagos que aumentam estas cotas. O serviço inclui de graça um servidor de banco de dados replicado, com load-balancing, backup, e todos outros recursos que é normalmente perdemos um tempão configurando.
Algumas características:
- Banco de dados: O tratamento dos requests HTTP não possuem muita novidade, mas em relação ao banco de dados existe! O GAE oferece (obriga) o uso de um banco de dados não relacional. Em Python isso é bem chato, porque a API é mais baixo nível do que a oferecida pelo Django, mas ela é escrita assim para incentivar o desenvolvedor a otimizar a todo momento suas querys, para diminuir o uso das cotas de acesso ao banco. Acredito que num futuro não muito distante, a Google irá disponibilizar algum Wrapper que facilita a escrita de algumas queries.
- Segurança: Como é de se esperar, existem diversas limitações por questão de segurança, o Google não vai permitir que coloquem vírus ou código malicioso dentro de suas máquinas, certo? Por isso, as funcionalidades críticas de segurança de um sistema, como acesso ao sistema de arquivos e criação de threads são bloqueadas.
Agora também é suportado no GAE a linguagem Java (a primeira linguagem que teve suporte foi Python), consequentemente todas as linguagens que rodam em cima da JVM: Scala, Groovy, Jython, JRuby...
Aqui um exemplo de uma aplicação em Scala rodando no GAE
http://lift-example.appspot.com/index
O framework Lift também é compatível, mas precisaram fazer umas adaptações, principalmente porque o Lift utliza muitos atores em sua implementação. Segue um novo branch do framework Lift que está adaptado ao GAE: http://github.com/ymnk/liftweb/tree/master.
Mais informações:
Scala
- Scala works out of the box.
- Scala Actors do not work, because they are implemented using Threads (which are not supported).
- The Lift web framework works. David Pollak has additional details.
Dave Briccetti posted on his experiences using Scala and JavaServer Faces:
http://briccetti.blogspot.com/2009/04/my-first-scala-web-app-on-goo...
GAE e Java:
http://groups.google.com/group/google-appengine-java/web/will-it-pl...
Algumas características:
- Banco de dados: O tratamento dos requests HTTP não possuem muita novidade, mas em relação ao banco de dados existe! O GAE oferece (obriga) o uso de um banco de dados não relacional. Em Python isso é bem chato, porque a API é mais baixo nível do que a oferecida pelo Django, mas ela é escrita assim para incentivar o desenvolvedor a otimizar a todo momento suas querys, para diminuir o uso das cotas de acesso ao banco. Acredito que num futuro não muito distante, a Google irá disponibilizar algum Wrapper que facilita a escrita de algumas queries.
- Segurança: Como é de se esperar, existem diversas limitações por questão de segurança, o Google não vai permitir que coloquem vírus ou código malicioso dentro de suas máquinas, certo? Por isso, as funcionalidades críticas de segurança de um sistema, como acesso ao sistema de arquivos e criação de threads são bloqueadas.
Agora também é suportado no GAE a linguagem Java (a primeira linguagem que teve suporte foi Python), consequentemente todas as linguagens que rodam em cima da JVM: Scala, Groovy, Jython, JRuby...
Aqui um exemplo de uma aplicação em Scala rodando no GAE
http://lift-example.appspot.com/index
O framework Lift também é compatível, mas precisaram fazer umas adaptações, principalmente porque o Lift utliza muitos atores em sua implementação. Segue um novo branch do framework Lift que está adaptado ao GAE: http://github.com/ymnk/liftweb/tree/master.
Mais informações:
Scala
- Scala works out of the box.
- Scala Actors do not work, because they are implemented using Threads (which are not supported).
- The Lift web framework works. David Pollak has additional details.
Dave Briccetti posted on his experiences using Scala and JavaServer Faces:
http://briccetti.blogspot.com/2009/04/my-first-scala-web-app-on-goo...
GAE e Java:
http://groups.google.com/group/google-appengine-java/web/will-it-pl...
Casos de Sucesso com Scala: Twitter
http://twitter.com/
Entrevista com um dos criados do Twitter: http://www.radicalbehavior.com/5-question-interview-with-twitter-de...
O autor Alex Payne também escreveu um livro sobre Scala com Dean Wampler: Programming Scala: Rough Cuts Version
Entrevista com um dos criados do Twitter: http://www.radicalbehavior.com/5-question-interview-with-twitter-de...
O autor Alex Payne também escreveu um livro sobre Scala com Dean Wampler: Programming Scala: Rough Cuts Version
Aprendendo Scala
Pra quem quiser aprender Scala, existe duas apresentações bem legais sobre o assunto (links abaixo), apesar de ser slides, muita coisa é intuitiva e fácil de entender. É um ótimo tutorial inicial para o impaciente!
OOPSLA 2008: The Scala Experience por Bill Venners
Java One: Safe Programming Can be Fun! por Martin Odersky
OOPSLA 2008: The Scala Experience por Bill Venners
Java One: Safe Programming Can be Fun! por Martin Odersky
Scala vs Java
Seguindo a idéia do post passado, segue um post para aguçar a discussão sobre linguagens, segue algumas comparações entre as duas linguagens, seguindo as características mencionadas no post anterior.
Obs: A conclusão do post não fica em cima do muro =)
- Performance
Java ? Scala: Código de Scala é convertido para bytecodes que são executados pela JVM, mas sempre tem um pequeno código adicional que afeta um pouco a performance, mas nada comparado com Groovy que é interpretada. Desta forma, apenas para não ser injusto com Java, vale a pena enfatizar isso, mas não é nada significante para deixar de usar em um ambiente de produção. Um ponto positivo de Scala é que o suporte a processadores multi-core existe, por isso programas paralelos em Scala tem potencial para serem mais rápicos que em Java.
- Produtividade
Java > Scala: A sintaxe de Scala torna a linguagem muito mais produtiva que Java, por outro lado as ferramentas e IDEs de Java até o momento propiciam uma maior produtividade, por isso por enquanto Java ainda é mais produtiva.
- Sintaxe bonita
Scala > Java: Scala é uma linguagem com tipagem estática esperta, que minimiza a escrita de definição de tipos quando possível. Ao contrário de Java, que é verbosa e repetitiva, compare os exemplos abaixo:
Java: Aluno aluno = new Aluno
Scala: aluno = new Aluno ou aluno:Aluno = _
Java: String string = "x"
Scala: string = "x"
- Boas IDEs
Java > Scala: O plugin do Eclipse para Scala está muito bugado, mas é questão de tempo para que ele fique estável, pois existe um time muito ativo na comunidade. Os plugins do Eclipse também não estão estáveis, por exemplo o arcabouço do JUnit que é super estável em Java, para Eclipse não funciona muito bem. Já o TestNG tem um melhor suporte no momento. O JUnitMax ainda não funciona para Scala, mas ainda está em versão Alpha mesmo para Java.
O NetBeans e o Intellij tem um suporte muito bom a Scala, bem melhor que do Eclipse, mas com certeza não estão tão estáveis quanto o suporte a Java. Mas novamente, questão de tempo para obter a estabilidade das IDEs de Java.
- API completa, extensível e fácil de usar
Scala > Java: Scala possui uma API extra, além de suportar toda API do Java, desta forma não tem como Scala ficar para trás.
- Ferramentas e Frameworks produtivos e completos
Java > Scala: Suas aplicações Web escritas com Lift rodam em cima de um Tomcat ou JBoss tranquilamente. Por outro lado, JPA, arcabouços de mocks, JUnitMax etc, não funcionam com Scala ou exigem alguns cuidados e adaptações. Por isso, temporariamente, Scala ainda tem um défict em relação a estabilidade das ferramentas e frameworks de Java.
- Suporte a orientação a objetos
Scala > Java:
- Scala obriga a escrita de override (em Java a opcional anotação @Override), obrigando esta boa prática de programação OO.
- Scala subistitui a noção de Interface com Trait, que é uma Interface mais poderosa, que aceita implementação, como uma classe abstrata. Com traits é possível escrever uma Interface, já com Interface não é possível escrever traits. Desta forma, o suporte a herança múltipla em Scala é mais rico que em Java, sem o problema do Diamante em herança múltipla.
- Como Java, Scala também possui suporte a generics.
- Em Scala é possível escrever mais de uma classe pública em um mesmo arquivo. Isto é útil para evitar infinitos arquivos para aqueles casos que temos que escrever diversas classes pequenas (que algumas vezes pode indicar um erro de design).
- Scala não possui switch, que estimula a escrita na forma de programação modular.
- Scala não possui métodos estáticos, que complicam o uso de mocks e atrapalham muitas vezes o design da aplicação.
- Suporte a orientação a aspectos
Java > Scala: Devido a estabilidade do AspectJ em Java.
- Suporte a programação funcional
Scala > Java: Java ainda não suporta blocos. A escrita de blocos a partir de classes anônimas em Java é muito precário. Já Scala possui suporte nativo a programação funcional.
- Suporte a reflexão
Scala ?<>? Java: Scala não possui a palavra reservada class. Temos que usar getClass como em Java ou classOf[], Ponto chato é que para instanciar classes em Scala é necessário adicionar o termo $class, que suja o código. De resto, não conheço alguma grande vantagem ou desvantagem, alguém já estudou isso?
- Tipagem estática ou dinâmica ou as duas
É possível rodar Scala com JRuby ou Jython, mas não com a estabilidade de Java, então se preferir unir os dois paradigmas, ainda Java é preferível sobre Scala. Mas pensando apenas em tipagem estática, Scala supera Java já que sua sintaxe é muito mais inteligente, ou não verbosa como a de Java.
- Bom suporte a programação concorrente ou paralela
Scala > Java: Java trabalha com threads enquanto Scala com atores, como Erlang. Criar threads é muito mais barato do que criar Processos no SO, por isso muitas linguagens trabalham com threads. Por outro lado, com threads não é possível aproveitar todo potencial que os novos processadores multi-core possuem. Por isso Scala trabalha com Mini-Processos, que são mais leves que os processos tradicionais e possibilitam o aproveitamento dos vários processadores da máquina.
- Interpretada ou compilada
Scala = Java: Código em Scala é convertido em bytecodes, como Java. Existem compiladores pagos para bytecodes, mas não importa de qual linguagem veio.
- Multi-plataforma
Scala = Java: Todos os SOs que JVM suporta.
- Código aberto
Scala > Java: Scala já nasceu com o código aberto, isto deve agilizar sua evolução desde o princípio, assim como aconteceu com Ruby.
Conclusão: Apesar de todos benefícios de Scala sobre Java, até o momento, ainda é preferível utilizar Java em um ambiente real de produção, mas isto pode mudar drásticamente nos próximos meses, por isso, quem gosta de linguagem com tipagem estática já pode ir estudando e fuçando Scala para chegar com tudo =)
Obs: A conclusão do post não fica em cima do muro =)
- Performance
Java ? Scala: Código de Scala é convertido para bytecodes que são executados pela JVM, mas sempre tem um pequeno código adicional que afeta um pouco a performance, mas nada comparado com Groovy que é interpretada. Desta forma, apenas para não ser injusto com Java, vale a pena enfatizar isso, mas não é nada significante para deixar de usar em um ambiente de produção. Um ponto positivo de Scala é que o suporte a processadores multi-core existe, por isso programas paralelos em Scala tem potencial para serem mais rápicos que em Java.
- Produtividade
Java > Scala: A sintaxe de Scala torna a linguagem muito mais produtiva que Java, por outro lado as ferramentas e IDEs de Java até o momento propiciam uma maior produtividade, por isso por enquanto Java ainda é mais produtiva.
- Sintaxe bonita
Scala > Java: Scala é uma linguagem com tipagem estática esperta, que minimiza a escrita de definição de tipos quando possível. Ao contrário de Java, que é verbosa e repetitiva, compare os exemplos abaixo:
Java: Aluno aluno = new Aluno
Scala: aluno = new Aluno ou aluno:Aluno = _
Java: String string = "x"
Scala: string = "x"
- Boas IDEs
Java > Scala: O plugin do Eclipse para Scala está muito bugado, mas é questão de tempo para que ele fique estável, pois existe um time muito ativo na comunidade. Os plugins do Eclipse também não estão estáveis, por exemplo o arcabouço do JUnit que é super estável em Java, para Eclipse não funciona muito bem. Já o TestNG tem um melhor suporte no momento. O JUnitMax ainda não funciona para Scala, mas ainda está em versão Alpha mesmo para Java.
O NetBeans e o Intellij tem um suporte muito bom a Scala, bem melhor que do Eclipse, mas com certeza não estão tão estáveis quanto o suporte a Java. Mas novamente, questão de tempo para obter a estabilidade das IDEs de Java.
- API completa, extensível e fácil de usar
Scala > Java: Scala possui uma API extra, além de suportar toda API do Java, desta forma não tem como Scala ficar para trás.
- Ferramentas e Frameworks produtivos e completos
Java > Scala: Suas aplicações Web escritas com Lift rodam em cima de um Tomcat ou JBoss tranquilamente. Por outro lado, JPA, arcabouços de mocks, JUnitMax etc, não funcionam com Scala ou exigem alguns cuidados e adaptações. Por isso, temporariamente, Scala ainda tem um défict em relação a estabilidade das ferramentas e frameworks de Java.
- Suporte a orientação a objetos
Scala > Java:
- Scala obriga a escrita de override (em Java a opcional anotação @Override), obrigando esta boa prática de programação OO.
- Scala subistitui a noção de Interface com Trait, que é uma Interface mais poderosa, que aceita implementação, como uma classe abstrata. Com traits é possível escrever uma Interface, já com Interface não é possível escrever traits. Desta forma, o suporte a herança múltipla em Scala é mais rico que em Java, sem o problema do Diamante em herança múltipla.
- Como Java, Scala também possui suporte a generics.
- Em Scala é possível escrever mais de uma classe pública em um mesmo arquivo. Isto é útil para evitar infinitos arquivos para aqueles casos que temos que escrever diversas classes pequenas (que algumas vezes pode indicar um erro de design).
- Scala não possui switch, que estimula a escrita na forma de programação modular.
- Scala não possui métodos estáticos, que complicam o uso de mocks e atrapalham muitas vezes o design da aplicação.
- Suporte a orientação a aspectos
Java > Scala: Devido a estabilidade do AspectJ em Java.
- Suporte a programação funcional
Scala > Java: Java ainda não suporta blocos. A escrita de blocos a partir de classes anônimas em Java é muito precário. Já Scala possui suporte nativo a programação funcional.
- Suporte a reflexão
Scala ?<>? Java: Scala não possui a palavra reservada class. Temos que usar getClass como em Java ou classOf[], Ponto chato é que para instanciar classes em Scala é necessário adicionar o termo $class, que suja o código. De resto, não conheço alguma grande vantagem ou desvantagem, alguém já estudou isso?
- Tipagem estática ou dinâmica ou as duas
É possível rodar Scala com JRuby ou Jython, mas não com a estabilidade de Java, então se preferir unir os dois paradigmas, ainda Java é preferível sobre Scala. Mas pensando apenas em tipagem estática, Scala supera Java já que sua sintaxe é muito mais inteligente, ou não verbosa como a de Java.
- Bom suporte a programação concorrente ou paralela
Scala > Java: Java trabalha com threads enquanto Scala com atores, como Erlang. Criar threads é muito mais barato do que criar Processos no SO, por isso muitas linguagens trabalham com threads. Por outro lado, com threads não é possível aproveitar todo potencial que os novos processadores multi-core possuem. Por isso Scala trabalha com Mini-Processos, que são mais leves que os processos tradicionais e possibilitam o aproveitamento dos vários processadores da máquina.
- Interpretada ou compilada
Scala = Java: Código em Scala é convertido em bytecodes, como Java. Existem compiladores pagos para bytecodes, mas não importa de qual linguagem veio.
- Multi-plataforma
Scala = Java: Todos os SOs que JVM suporta.
- Código aberto
Scala > Java: Scala já nasceu com o código aberto, isto deve agilizar sua evolução desde o princípio, assim como aconteceu com Ruby.
Conclusão: Apesar de todos benefícios de Scala sobre Java, até o momento, ainda é preferível utilizar Java em um ambiente real de produção, mas isto pode mudar drásticamente nos próximos meses, por isso, quem gosta de linguagem com tipagem estática já pode ir estudando e fuçando Scala para chegar com tudo =)
Poker Texas Hold'Em em Scala
Segue uma implementação do jogo Poker Texas Hold'Em em Scala:
http://ccsl.ime.usp.br/agilcoop/files/PokerTexasHoldEm.zip
Tem alguns algoritmos bacanas, testes de unidade com TestNG (até o momento o melhor suporte para Eclipse), e vários aspectos legais para aprender Scala.
http://ccsl.ime.usp.br/agilcoop/files/PokerTexasHoldEm.zip
Tem alguns algoritmos bacanas, testes de unidade com TestNG (até o momento o melhor suporte para Eclipse), e vários aspectos legais para aprender Scala.
Comparações entre linguagens
Quando vamos discutir sobre linguagens de programação, alguns comportamentos são típicos: Uns tentam puxar a sardinha pro que lhe convém, outros fogem da raia e dizem que não existe uma linguagem perfeita e fim de papo.
Hoje estamos mais evoluidos e novos paradigmas estão surgindo. A interminável guerra entre tipagem estática ou dinâmica está a ponto de receber um pouco mais de emoção com o surgimento do JRuby e Jython que misturam os dois paradigmas. Também está ficando mais interessante as discussões sobre conceitos de programação, como orientação a objetos, programação funcional, orientação a aspectos e reflexão que podem ser utilizados juntos e de forma amigável, principalmente com linguagens com bom suporte como Smalltalk, Python, Ruby e Scala, entre outras.
Minha opinião é que pode existir sim uma linguagem perfeita, que atenda a todas a necessidades, mas ainda deve demorar para chegarmos as conclusões pertinentes para isso. Para pensarmos sobre isso, temos que pensar o que esperamos de uma linguagem, destaco algumas características interessantes:
- Performance
- Produtividade
- Sintaxe bonita
- Boas IDEs
- API completa, extensível e fácil de usar
- Frameworks produtivos e completos
- Suporte a orientação a objetos
- Suporte a orientação a aspectos
- Suporte a programação funcional
- Suporte a reflexão
- Tipagem estática ou dinâmica ou as duas
- Bom suporte a programação concorrente ou paralela
- Interpretada ou compilada
- Multi-plataforma
- Código aberto
- ente infinitos outros
Se formos pensar só em performance, escolheriamos C++ ou Lua, pensando em sintaxe bonita escolheriamos Python, considerando frameworks produtivos escolheriamos Ruby (por causa do Rails), bom suporte a programação concorrente ou paralesla optaríamos por Scala, boa IDE escolheríamos Java (com Eclipse + JUnitMax) e por ai vai.
Destas características, algumas são incostestáveis, por exemplo, todos querem melhor performance. Em relação às APIs e frameworks também. Quem não prefere fazer print("alguma coisa") ao invés de System.out.println("alguma coisa")?? Lembro que quando comecei a aprender Java eu achava lindo fazer "new BufferedReader(new FileReader(new InputStreamReader(new InternalAlgumaCoisaReader(new BytecodeReader(..." porque sabia que a orientação a objetos por trás desta API estava muito bonita, mas depois de um tempo isto me torrou a paciência.
Já em relação aos conceitos de programação, todos são compatíveis e podem trabalhar juntos em perfeita harmonia, vide exemplos como Java + AspectJ, Hibernate + Reflection, Ruby OO + Ruby funcional, etc..
O que acho que é o mais crítico e difícil de chegar a uma conclusão é em relação a tipagem. Escrever código com tipagem dinâmica é muito mais gostoso, por outro lado trabalhar com o auxílio do compilador também é, não é uma delícia dar control+espaço e a IDE completa o resto pra gente? E agora? Alguns usam como argumentos a facilidade de refatoração, por exemplo Java possui um suporte a refatoração esplêndido, mas SmallTalk e Python também! Então fica complicado chegar a alguma conclusão a partir deste argumento.
Bom, enfim, o objetivo deste post não era concluir nada, é só para aguçar a discussão e talvez estimular posts como "Scala vs Java", "Scala vs Python", "Scala vs Ruby", "Scala vs Haskell", "Scala vs Groovy", que acho uma excelente maneira da gente entender melhor os pontos fortes e fracos das linguagens.
Hoje estamos mais evoluidos e novos paradigmas estão surgindo. A interminável guerra entre tipagem estática ou dinâmica está a ponto de receber um pouco mais de emoção com o surgimento do JRuby e Jython que misturam os dois paradigmas. Também está ficando mais interessante as discussões sobre conceitos de programação, como orientação a objetos, programação funcional, orientação a aspectos e reflexão que podem ser utilizados juntos e de forma amigável, principalmente com linguagens com bom suporte como Smalltalk, Python, Ruby e Scala, entre outras.
Minha opinião é que pode existir sim uma linguagem perfeita, que atenda a todas a necessidades, mas ainda deve demorar para chegarmos as conclusões pertinentes para isso. Para pensarmos sobre isso, temos que pensar o que esperamos de uma linguagem, destaco algumas características interessantes:
- Performance
- Produtividade
- Sintaxe bonita
- Boas IDEs
- API completa, extensível e fácil de usar
- Frameworks produtivos e completos
- Suporte a orientação a objetos
- Suporte a orientação a aspectos
- Suporte a programação funcional
- Suporte a reflexão
- Tipagem estática ou dinâmica ou as duas
- Bom suporte a programação concorrente ou paralela
- Interpretada ou compilada
- Multi-plataforma
- Código aberto
- ente infinitos outros
Se formos pensar só em performance, escolheriamos C++ ou Lua, pensando em sintaxe bonita escolheriamos Python, considerando frameworks produtivos escolheriamos Ruby (por causa do Rails), bom suporte a programação concorrente ou paralesla optaríamos por Scala, boa IDE escolheríamos Java (com Eclipse + JUnitMax) e por ai vai.
Destas características, algumas são incostestáveis, por exemplo, todos querem melhor performance. Em relação às APIs e frameworks também. Quem não prefere fazer print("alguma coisa") ao invés de System.out.println("alguma coisa")?? Lembro que quando comecei a aprender Java eu achava lindo fazer "new BufferedReader(new FileReader(new InputStreamReader(new InternalAlgumaCoisaReader(new BytecodeReader(..." porque sabia que a orientação a objetos por trás desta API estava muito bonita, mas depois de um tempo isto me torrou a paciência.
Já em relação aos conceitos de programação, todos são compatíveis e podem trabalhar juntos em perfeita harmonia, vide exemplos como Java + AspectJ, Hibernate + Reflection, Ruby OO + Ruby funcional, etc..
O que acho que é o mais crítico e difícil de chegar a uma conclusão é em relação a tipagem. Escrever código com tipagem dinâmica é muito mais gostoso, por outro lado trabalhar com o auxílio do compilador também é, não é uma delícia dar control+espaço e a IDE completa o resto pra gente? E agora? Alguns usam como argumentos a facilidade de refatoração, por exemplo Java possui um suporte a refatoração esplêndido, mas SmallTalk e Python também! Então fica complicado chegar a alguma conclusão a partir deste argumento.
Bom, enfim, o objetivo deste post não era concluir nada, é só para aguçar a discussão e talvez estimular posts como "Scala vs Java", "Scala vs Python", "Scala vs Ruby", "Scala vs Haskell", "Scala vs Groovy", que acho uma excelente maneira da gente entender melhor os pontos fortes e fracos das linguagens.
Grupos de Discussão sobre Scala
Grupos brasileiros:
http://groups.google.com/group/scala-br/
http://scala.org.br
Grupos estrangeiros:
Lift: http://groups.google.com/group/liftweb
Maven and Scala: http://groups.google.com/group/maven-and-scala?lnk=srg
http://groups.google.com/group/scala-br/
http://scala.org.br
Grupos estrangeiros:
Lift: http://groups.google.com/group/liftweb
Maven and Scala: http://groups.google.com/group/maven-and-scala?lnk=srg
Links bacanas para aprender Scala
Para Javeiros:
http://blogs.sun.com/sundararajan/entry/scala_for_java_programmers_...
http://lamp.epfl.ch/~emir/bqbase/2005/01/21/java2scala.html
http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees
Comparações de sintaxe de Java, Scala e Grrovy
http://www.jroller.com/aalmiray/entry/java_groovy_scala_side_to2
Scala, Oficial WebSite, APIs, etc:
http://www.scala-lang.org/
http://www.scala-lang.org/docu/files/api/index.html
http://scala-tools.org/scaladocs/scala-library/2.7.1/
http://www.scala-lang.org/node/257
http://www.scala-lang.org/node/91#other_scala_related
http://www.scala-lang.org/node/242
http://en.wikipedia.org/wiki/Scala_(programming_language)
Documentação, Artigos e Tutoriais:
http://www.scala-lang.org/node/143
IDE:
NetBeans atualmente tem melhor suporte para Scala. O plugin do eclipse para Scala ainda está bastante bugado, mas esta realidade deve mudar em breve, pessoal já está reservando uns dias para trabalhar nisso.
http://groups.google.com/group/scala-br/web/scala-com-o-eclipse
Lift (Web Framework):
http://liftweb.net/
http://liftweb.net/index.php/Main_Page
http://lambda-the-ultimate.org/node/2147
http://scala-blogs.org/
Ferramentas:
http://scala-blogs.org/2008/01/maven-for-scala.html
Testes Automatizados:
http://code.google.com/p/supereasymock/
http://lalitpant.blogspot.com/2007/12/using-jmock-with-scala.html
Também é provável que em breve o sensacional plugin JUnitMax detecte mudanças em arquivos que terminam com ".scala"
Blogs/Posts:
http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html
http://blogs.sun.com/sundararajan/entry/scala_for_java_programmers_...
http://lamp.epfl.ch/~emir/bqbase/2005/01/21/java2scala.html
http://www.codecommit.com/blog/scala/roundup-scala-for-java-refugees
Comparações de sintaxe de Java, Scala e Grrovy
http://www.jroller.com/aalmiray/entry/java_groovy_scala_side_to2
Scala, Oficial WebSite, APIs, etc:
http://www.scala-lang.org/
http://www.scala-lang.org/docu/files/api/index.html
http://scala-tools.org/scaladocs/scala-library/2.7.1/
http://www.scala-lang.org/node/257
http://www.scala-lang.org/node/91#other_scala_related
http://www.scala-lang.org/node/242
http://en.wikipedia.org/wiki/Scala_(programming_language)
Documentação, Artigos e Tutoriais:
http://www.scala-lang.org/node/143
IDE:
NetBeans atualmente tem melhor suporte para Scala. O plugin do eclipse para Scala ainda está bastante bugado, mas esta realidade deve mudar em breve, pessoal já está reservando uns dias para trabalhar nisso.
http://groups.google.com/group/scala-br/web/scala-com-o-eclipse
Lift (Web Framework):
http://liftweb.net/
http://liftweb.net/index.php/Main_Page
http://lambda-the-ultimate.org/node/2147
http://scala-blogs.org/
Ferramentas:
http://scala-blogs.org/2008/01/maven-for-scala.html
Testes Automatizados:
http://code.google.com/p/supereasymock/
http://lalitpant.blogspot.com/2007/12/using-jmock-with-scala.html
Também é provável que em breve o sensacional plugin JUnitMax detecte mudanças em arquivos que terminam com ".scala"
Blogs/Posts:
http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html
Design Patterns em Scala: Observer
Observer é um padrão muito legal, principalmente quando vamos trabalhar com a arquitetura MVC ou parecidas. O padrão MVC 'original' utiliza o padrão observer, mas como só falamos em Web, e os frameworks Web fornecem uma arquitetura MVC sem o observer (sem um Push no client), então vamos esquecendo... Dá para pensar no Observer para Web por exemplo com o framework Comet para Java, consequentemente para Scala.
Segue uma implementação:
Observer.scala
package scala.behavioral
import scala.collection.jcl.ArrayList
// Observer = Publisher-Subscriber
// Dependência 1-N onde os N dependentes serão notificados e atualizos a cada mudança de estado do objeto que está sendo observado
// Abstract implementation
trait Observable { // Publisher
val observers = new ArrayList[Observer]()
def notifyObservers() {
for(observer <- observers)
observer.notification()
}
def addObserver(observer:Observer) {
observers += observer
}
def removeObserver(observer:Observer) {
observers -= observer
}
}
trait Observer { // Subscriber
def notification()
}
// Concrete Implementation
class SomeObservable extends Observable
class SomeObserver extends Observer {
override def notification() {
println("do something here: SomeObserver")
}
}
class AnotherObserver extends Observer {
override def notification() {
println("do something here: AnotherObserver")
}
}
// Client
object ObserverClient extends Application {
var observable = new SomeObservable()
var observer1 = new SomeObserver()
var observer2 = new AnotherObserver()
observable.addObserver(observer1)
observable.addObserver(observer2)
observable.notifyObservers()
observable.removeObserver(observer2)
observable.notifyObservers()
}
Design Patterns em Scala: Facade
Facade:
Facade.scala
package scala.structural
// Facilita o uso de um sistema unificando o comportamento de diversos objetos
// Concrete Implementation
trait SubSystemA {
def methodA1()
def methodA2()
}
trait SubSystemB {
def methodB()
}
class ConcreteSubSystemA extends SubSystemA {
override def methodA1() {
println("System A")
}
override def methodA2() {
println("System A")
}
}
class ConcreteSubSystemB extends SubSystemB {
override def methodB() {
println("System B")
}
}
class Facade extends SubSystemA with SubSystemB {
val subsystemA = new ConcreteSubSystemA()
val subsystemB = new ConcreteSubSystemB()
override def methodA1() {
subsystemA.methodA1()
}
override def methodA2() {
subsystemA.methodA2()
}
override def methodB() {
subsystemB.methodB()
}
}
// Client
object FacadeClient extends Application {
var facade = new Facade()
facade.methodA1()
facade.methodA2()
facade.methodB()
}
Design Patterns em Scala: State
Segue mais dois padrões de projeto em Scala:
State:
State.scala
package scala.behavioral
// Mudar o comportamento mude de acordo com seu estado
// Abstract Implementation
class Context {
var state:State = _
state = new NullState()
def handle() {
state.handle()
}
}
trait State {
def handle()
}
// Concrete Implementation
class NullState extends State {
override def handle() {
println("blank algorithm, maybe throw an exception of unitilized context")
}
}
class StateA extends State {
override def handle() {
println("algorithm for state A")
}
}
class StateB extends State {
override def handle() {
println("algorithm for state B")
}
}
// Client
object StateClient extends Application {
var context = new Context()
context.state = new StateA()
context.handle()
context.state = new StateB()
context.handle()
}
Design Patterns em Scala: Strategy
Strategy é um dos padrões mais legais na minha opinião, juntamente com Template Method, Command, Observer, entre outros.
Com Scala dá pra implementar o Strategy com pelo menos duas maneiras diferentes: O comum, extendendo um Trait com a interface da estratégia/algoritmo, ou então utilizando o objeto método como sendo um algoritmo. Já que em Scala (assim como em outras linguagens inteiramente OO) o método é um objeto, isto é, podemos chamar métodos de um método, podemos passar métodos como parâmetros, etc, não há a necessidade de encapsularmos um algoritmo dentro de uma classe.
Segue as duas versões:
Encapsulando o algoritmo em objetos:
Strategy.scala
package scala.behavioral
// Strategy = Policy
// Encapsular um algoritmo para que ele possa ser alterado dinamicamente
// Abstract Implementation
trait Strategy {
def run() { // Template method for legibility
algorithm()
}
def algorithm()
}
// Concrete Implementation
class DefaulStrategy extends Strategy {
override def algorithm() {
println("default algorithm")
}
}
class StrategyA extends Strategy {
override def algorithm() {
println("solved using algorithm A")
}
}
class StrategyB extends Strategy {
override def algorithm() {
println("solved using algorithm B")
}
}
class MyApplication(var strategy:Strategy) {
def doSomething() {
strategy.run()
}
}
// Client
object StrategyClient extends Application {
var arg = "a"
var strategy:Strategy = _
arg match {
case "a" => strategy = new StrategyA()
case "b" => strategy = new StrategyB()
case _ => strategy = new DefaulStrategy()
}
var myapp = new MyApplication(strategy)
myapp.doSomething()
myapp.strategy = new StrategyB()
myapp.doSomething()
}
Utilizando o próprio objeto método:
Strategy2.scala
package scala.behavioral
// Strategy = Policy
// Encapsular um algoritmo para que ele possa ser alterado dinamicamente
// Example with function-objects
// Concrete Implementation
class SomeParam
class SomeReturnValue
object Strategies {
def strategyA(param:SomeParam) : SomeReturnValue = {
println("strategy A")
return new SomeReturnValue()
}
def strategyB(param:SomeParam) : SomeReturnValue = {
println("strategy B")
return new SomeReturnValue()
}
def strategyC(param:SomeParam) : SomeReturnValue = {
println("strategy C")
return new SomeReturnValue()
}
}
class MyApplication2(var strategy: (SomeParam => SomeReturnValue)) {
def doSomething(param:SomeParam) : SomeReturnValue = {
return strategy(param)
}
}
// Client
object StrategyClient2 extends Application {
var arg = "a"
var strategy:(SomeParam => SomeReturnValue) = _
arg match {
case "a" => strategy = Strategies.strategyA
case "b" => strategy = Strategies.strategyB
case _ => strategy = Strategies.strategyC
}
var myapp = new MyApplication2(strategy)
myapp.doSomething(new SomeParam())
myapp.strategy = Strategies.strategyC
myapp.doSomething(new SomeParam())
}
Design Patterns em Scala: Chain of Responsibility
Design Patterns são fundamentais para um bom design O.O., para quem não conhece, existem diversos livros excelentes sobre o assunto, por exemplo: GoF e em Java
Abaixo segue alguns padrões em Scala:
Chain of Responsability:
ChainOfResponsability.scala
Abaixo segue alguns padrões em Scala:
Chain of Responsability:
ChainOfResponsability.scala
package scala.behavioral
import scala.collection.jcl.ArrayList
abstract class HandlerResponsability[D,V]() {
var responsable = false
def isResponsable():Boolean = responsable
def execute(data:D) : V
}
// Composite style
class ChainOfResponsability[D,V] extends HandlerResponsability[D, V] {
this.responsable = true
val handlers = new ArrayList[HandlerResponsability[D,V]]()
override def execute(data:D) : V = {
for(handler <- handlers) {
var value = handler.execute(data)
if(handler.isResponsable())
return value
}
throw new RuntimeException("Throw unsolved or return a default value")
}
def addHandler(handler:HandlerResponsability[D,V]) {
handlers += handler
}
}
class MyData(val value:Int)
class MyResult(val str:String) {
override def toString():String = str
}
class SomeConcreteHandler extends HandlerResponsability[MyData, MyResult] {
override def execute(data:MyData) : MyResult = {
// set true or false, depends on the data
println("Running SomeConcreteHandler")
if(data.value == 5) {
this.responsable = true
return new MyResult("result from SomeConcreteHandler")
}
return null
}
}
class AnotherConcreteHandler extends HandlerResponsability[MyData, MyResult] {
override def execute(data:MyData) : MyResult = {
println("Running AnotherConcreteHandler")
// set true or false, depends on the data
if(data.value == 3) {
this.responsable = true
return new MyResult("result from AnotherConcreteHandler")
}
return null
}
}
// Composite style
class MyChainOfResponsability extends ChainOfResponsability[MyData, MyResult] {
super.addHandler(new SomeConcreteHandler())
super.addHandler(new AnotherConcreteHandler())
}
object ChainOfResponsabilityClient extends Application {
var handler = new MyChainOfResponsability()
println(handler.execute(new MyData(3)))
println(handler.execute(new MyData(5)))
}
Plugins pro Eclipse
Python:
Java:
ajdt (AspectJ): http://download.eclipse.org/tools/ajdt/34/update
maven: http://m2eclipse.sonatype.org/update
Scala:
scala: http://www.scala-lang.org/scala-eclipse-plugin-nigthly
Groovy:
groovy/grails: http://dist.codehaus.org/groovy/distributions/update/
Métricas:
eclemma: http://update.eclemma.org
coverclipse: http://coverlipse.sf.net/update
metrics: http://www.stateofflow.com/UpdateSite
Testes:
testng: http://beust.com/eclipse
jsunit: download http://sourceforge.net/projects/jsunit/files/
Controle de Versão:
subclipse: http://subclipse.tigris.org/update_1.0.x
ajdt (AspectJ): http://download.eclipse.org/tools/ajdt/34/update
maven: http://m2eclipse.sonatype.org/update
Scala:
scala: http://www.scala-lang.org/scala-eclipse-plugin-nigthly
Groovy:
groovy/grails: http://dist.codehaus.org/groovy/distributions/update/
Métricas:
eclemma: http://update.eclemma.org
coverclipse: http://coverlipse.sf.net/update
metrics: http://www.stateofflow.com/UpdateSite
Testes:
testng: http://beust.com/eclipse
jsunit: download http://sourceforge.net/projects/jsunit/files/
Controle de Versão:
subclipse: http://subclipse.tigris.org/update_1.0.x
Assinar:
Postagens (Atom)