quinta-feira, 7 de maio de 2009

Java e linguagens dinâmicas

Ontem andei conversando com um amigo que tem a opinião que eu tinha em 2004/5: ele acredita que HOJE, Java está tão evoluído que não há necessidade de se utilizar alguma outra linguagem para solucionar qualquer problema na empresa em que estamos trabalhando. Eu fui contra e defendi a minha opinião atual do uso de Python, Groovy, Ruby, Bash ou de qualquer outra linguagem e/ou framework que for necessária para entregar uma boa solução para um problema, rapidamente e com qualidade. Escrevo este post para ele e para todos os outros amigos Javaneses que tenho e que talvez, tenham uma opinião/visão similar. Eu também gostaria muito de ter seu comentário sobre este assunto em meu blog.

Eu, estive palestrando no FISL em 2006 (baixe a apresentação). Ele ocorreu em Porto Alegre, e eu pude ver o quanto a comunidade open source do Brasil é mista. Naquela época, o Ruby on Rails estava começando a aparecer mundialmente como um framework altamente produtivo para a produção de aplicações Web 2.0. Meu intuito era falar sobre como o Java poderia estar mais próximo do que o Ruby fazia utilizando linguagens dinâmicas como o Groovy, JRuby ou frameworks como o Grails, Trails, etc e, a conclusão final era que Java, para se tornar melhor, não deveria mais ser vista como a LINGUAGEM Java, mas sim, como a PLATAFORMA Java. Pois bem, isto foi em 2006. Três anos depois, eu ainda defendo esta opinião. Estão aí no mercado produtos como Groovy, Rhino, Jython, JRuby. Excelentes frameworks Java como o Spring e o Seam fazem uso do Groovy. A SpringSource (dona do Spring) foi ainda mais longe e adquiriu a G2One (que era a dona do Groovy). O lista de usuário do Grails no Brasil cresceu muito de uns tempos para cá. E até mesmo o Ruby on Rails roda no JRuby, se você quiser. Ou seja, Java está realmente consolidando o conceito de PLATAFORMA, e a LINGUAGEM Java é apenas mais uma que roda nela. E eu digo mais: você consegue ser mais efetivo e programar mais, com menos código, se for utilizar linguagens dinâmicas como o Groovy ou o Python. Se você tiver a necessidade de se aproveitar de algum legado Java, utilize a PLATAFORMA Java e tente ser mais "dinâmico" utilizando o Groovy, por exemplo. Se você acha o Seam produtivo e gosta de utilizá-lo, eu lhe digo que você pode ser ainda mais produtivo com o seu uso, se utilizá-lo junto com o Groovy.

Em 2006 eu conhecia Groovy e Ruby de leitura e testes caseiros. Não sabia nada de Python e tinha muita experiência em Java, C/C++ e Pascal. Do início do ano passado até hoje, eu posso dizer que me aprofundei muito em Bash e Groovy para solucionar meus problemas, e que Python tem sido a minha diversão neste momento. Utilizei o Bash para a automação da implantação de aplicações em diversas instâncias de JBoss do meu trabalho e, apesar da solução ter ficado legal, hoje eu acredito que se eu eu a tivesse desenvolvido em Python, por exemplo, teria escrito muito menos. Foi por isto que resolvi adotá-lo agora, num novo projeto que precisará de integração com o Subversion e com diversas aplicações do Linux. Outro processo que estou conduzindo neste momento, é a definição de uma estrutura legal para o build de diversas aplicações Java, hoje construídas com o Ant. Penso que a utilização do Groovy (ou de ferramentas que o utilizem como linguagem, como o Gant + Ivy ou o Gradle) seria uma das melhores alternativas. Outra alternativa, talvez em segundo lugar, seria a adoção do Maven.

Na minha opinião, bons desenvolvedores devem trabalhar com metodologias ágeis e utilizar as linguagens/ferramentas certas para cada ocasião. E as empresas devem incentivar esta característica. É claro que há um custo nisto e que talvez, possa até ser verdade que o gerenciamento seja mais difícil numa situação como esta. Mas, eu conheço algumas empresas no Brasil (algumas com mais de 100 desenvolvedores) que parecem não se preocupar com isto e adotam esta filosofia. Ou seja, elas utilizam as melhores soluções para os problemas, escolhendo a melhor linguagem para resolvê-lo. E, para mim, meu amigo tem sido um pouco controverso quando me diz, de vez em quando, uma frase que ele ouviu de outra pessoa: "Se você só tem um martelo como ferramenta, todos os parafusos são vistos como pregos!".

Atualmente, após me aventurar por linguagens tão dinâmicas quanto o Groovy e o Python, eu fico me perguntando porque ainda utilizo o Java. Eu tenho um outro amigo (Helder Moreira), do trabalho também, que diz para mim que ainda é o mainframe que paga o meu salário. Pode até ser, neste momento. E posso dizer também, que ainda vou depender do Java, por muito tempo, assim como meu amigo depende do mainframe. Mas, aprendendo outras linguagems, eu agora tenho um leque maior de alternativas para solucionar meus problemas. Eu sei de todas as características que tornaram Java, o sucesso que ele é, ainda hoje. Ministro cursos de Java e JBoss e de uma porção de frameworks e ferramentas para Java. Possuo algumas certificações da Sun e da Red Hat que, para mim, simplesmente comprovam que eu tinha estudado para uma prova e que talvez tivesse alguma experiência. Atualmente, programo com a LINGUAGEM Java criando extensões para o JBoss no ambiente do meu trabalho. Não tenho dúvida que ele é a melhor ferramenta em casos como este e em diversas outras situações. Mas, o que eu quero dizer com este texto é que Java, como linguagem, pode não ser a única e nem mesmo a melhor opção, em muitos casos.

Vou exemplificar com um programa ridículo e inútil, o que estou escrevendo. Daí então, você terá alguma base para comentar comigo, qualquer programa mais sério. Implementarei um programa, com os requisitos a seguir, em três linguagens diferentes (Java, Python e Groovy):

  1. Verificar se argumentos foram passados na linha de comando. Se nenhum for passado, a lista de argumentos deverá ser populada com três strings: "Nenhum", "argumento", "foi passado!";
  2. Imprimir os argumentos;
  3. Criar uma lista de strings contendo nomes de linguagens nesta ordem: JavaScript, Bash, Java, Python, Groovy
  4. Imprimir a lista de linguagens de maneira ordenada;
  5. Utilizar esta lista de linguagens para popular um mapa (chave=linguagem/valor=prioridade) das linguagens utilizadas no próximo projeto, por prioridade. A prioridade terá seu valor (de 0 a 10) obtido aleatoriamente;
  6. O mapa deverá ser impresso por ordem de prioridade, com a linguagem menos usada sendo impressa primeiro;
  7. Imprimir as cinco primeiras linhas do código do programa, lendo-as de seu arquivo fonte;

Antes de implementar este programa bobão, e de você me criticar dizendo que um programa idiota como este não deveria nem ser considerado por ser tão inútil, quero que você entenda que o meu objetivo é apenas comparar a sintaxe das linguagens e a facilidade de codificação para o desenvolvedor. Além disto, muitos programas são tão simples e idiotas como este. Não estou preocupado com qualquer outro tipo de requisito neste momento. Eu, como administrador de servidores de aplicações, sei muito bem que características uma aplicação real deve suportar num ambiente de produção, clusterizado, tolerante a falhas e não estou levando isto em consideração neste momento. Vou discutir isto em outro post.

Vou desconsiderar o cabeçalho dos programas (imports do Java, do Python e do Groovy) e começar em Java, a implementar os requisitos acima descritos, da maneira mais simples possível. No método main de uma classe Teste, o código a seguir implementa os requisitos 1, 2, 3 e 4:

if (args.length == 0) args = new String[] { "Nenhum", "argumento", "foi passado!" };
System.out.print("Lista dos argumentos passados: ");
for (String arg : args)
 System.out.print(arg + " ");
List<String> linguagens = new ArrayList<String>();
linguagens.add("JavaScript");
linguagens.add("Bash");
linguagens.add("Java");
linguagens.add("Python");
linguagens.add("Groovy");
System.out.print("\nLista ordenada de linguagens: ");
Collections.sort(linguagens);
for (String linguagem : linguagens)
 System.out.print(linguagem + " ");

O mesmo código poderia ser implementado em Python assim:

argv = sys.argv[1:]
if argv == []: argv = ["Nenhum", "argumento", "foi passado!"]
print 'Lista dos argumentos passados:', " ".join(argv)
linguagens = ["JavaScript", "Bash", "Java", "Python", "Groovy"]
print 'Lista ordenada de linguagens:', ' '.join(sorted(linguagens))

E, em Groovy, o código seria o seguinte:

if (args.size() == 0) args = [ "Nenhum", "argumento", "foi passado!" ]
println "Lista dos argumentos passados: ${args.join(" ")}"
def linguagens = ["JavaScript", "Bash", "Java", "Python", "Groovy"]
linguagens.sort()
println "Lista ordenada de linguagens: ${linguagens.join(" ")}"

Alguns comentários:

  • Em Java, como dito anteriormente, o código precisa estar dentro do método main de uma classe. Python e Groovy não tem esta limitação.
  • Em Python, o módulo sys contém o array argv. A questão é que o primeiro argumento deste array é sempre o nome do programa Python que está sendo executado. A sintaxe argv = sys.argv[1:] indica que a variável argv receberá uma cópia do array, mas iniciando pela posição 1, ao invés de 0.
  • Em Python, uma string tem um método join. Este método recebe uma lista e faz o contrário do split, ou seja, ele insere o contéudo da string " " entre os elementos do vetor recebido como parâmetro. Em Java, eu estou imprimindo um espaço a mais após o nome do argumento. O problema disto, é que se no lugar do espaço, fosse uma vírgula, ela iria sobrar após a impressão do último argumento. Se eu não quisesse que isto ocorresse, eu teria que trocar a sintaxe do for e testar se estou no último elemento. Caso estivesse, não concatenaria a string.
  • Em Groovy, a sintaxe é semelhante a do Python. Também estou utilizando o método join. Mas ele não é o método de uma string e sim de uma lista. Ele retorna uma string que terá, entre os elementos da lista de strings, o espaço informado como parâmetro. No Groovy utilizamos uma GString ao invés de uma String do Java e isto torna as coisas muito mais simples, como você viu.
  • Tanto Python quanto Groovy possuem uma sintaxe mais amigável para o trabalho com listas e mapas. Java não. Além disto, listas nestas duas linguagens possuem o método sort e o Python, suporta ainda, o build-in sorted que estou utilizando. No Java é necessário o uso do método sort de outra classe (Collections).
  • Sei que a quantidade de linhas não é uma boa métrica para indicar a facilidade de codificação, mas através da comparação desta métrica nas três linguagens, nós ficamos realmente tentados a pensar sobre isto.

Agora, vamos para a implementação dos requisitos 5 e 6:

Em Java:

Map<String, Integer> map = new LinkedHashMap<String, Integer>();
for (String linguagem : linguagens)
 map.put(linguagem, (int) ((Math.random() * 10)));
List<Map.Entry<String, Integer>> list = new Vector<Map.Entry<String, Integer>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
 public int compare(Map.Entry<String, Integer> entry, Map.Entry<String, Integer> entry1) {
     return (entry.getValue().equals(entry1.getValue()) ? 0 :
         (entry.getValue() > entry1.getValue() ? 1 : -1));
 }
});
map.clear();
for (Map.Entry<String, Integer> entry : list)
 map.put(entry.getKey(), entry.getValue());
System.out.print("\nLinguagens do proximo projeto (ordem por prioridade, de 0 a 10): ");
for (Map.Entry<String, Integer> entrySet : map.entrySet())
 System.out.print(String.format("%s (%d) ", entrySet.getKey(), entrySet.getValue()));

Em Python:

map = sorted(dict([nome, random.randint(0, 10)] for nome in linguagens).items(), key=lambda x: x[1])
print 'Linguagens do proximo projeto (ordem por prioridade, de 0 a 10):', \
 " ".join(["%s (%s)" % (item[0], item[1]) for item in map])

Em Groovy:

def map = [:]
linguagens.each{ map.put(it, new Random().nextInt(10)) }
print 'Linguagens do proximo projeto (ordem por prioridade, de 0 a 10): '
map.sort{ a, b -> a.value <=> b.value }.each{ k, v -> print "$k ($v) " }

Meus comentários:

  • Novamente, se eu fosse pensar em quantidade de linhas, comparando com Python ou Groovy, eu não utilizaria Java. Mas, como disse anteriormente, esta não é uma boa métrica. Vou então passar para a observação da clareza de sintaxe destas linguagens;
  • Generics é bom em Java até o momento em que a sintaxe começa a ficar estranha como a utilizada nesta solução. Eu pressuponho que você, leitor deste post, seja um programador Java mas, caso não seja, eu lhe peço: não se assuste! Muitos programadores Java quase chegam a ter um "orgasmo" ao ver um código como este que eu escrevi e acham ele lindo. Não os culpo. Eu também já passei por esta fase. Vou tentar explicar o que está ocorrendo no código Java:
    1. Crio um mapa cuja chave é uma string (nome da linguagem) e cujo valor é um inteiro (a prioridade);
    2. Populo o mapa, utilizando o for estendido do Java, a partir dos elementos da lista e obtendo o valor da prioridade como um número aleatório;
    3. Estruturas de dados como mapas podem ter elementos inseridos em ordem, se a implementação do mapa for uma árvore (TreeMap, por exemplo). Entretanto, a ordenação em mapas neste caso é realizada através da chave e não do valor. E eu preciso ordenar em função do valor. Sendo assim, meu próximo passo é criar uma lista onde, cada entrada do mapa, é um elemento. Daí então eu ordeno a lista com o método sort da classe Collections. Para realizar esta ordenação, eu utilizo um comparador que vai testar o valor de cada entrada e não a chave.
    4. O próximo passo é limpar o conteúdo da lista e populá-la novamente, com os elementos da lista ordenada. Como o mapa foi implementado como uma lista ligada, a ordem de inclusão será preservada ao percorrer a lista com o último for.
  • A sintaxe do Python é mais interessante e inteligente. Vou explicá-la:
    1. Montamos uma lista de tuplas "(linguagem, prioridade)" a partir da lista de linguagens utilizando uma característica do python chamada List Comprehensions
    2. O valor (de 0 a 10) da prioridade é obtido randomicamente a partir da função randint
    3. O build-in dict recebe esta lista e a transforma num mapa
    4. O build-in sorted recebe como parâmetros o mapa e um outro parâmetro. Este parâmetro é uma função anônima (lambda) que informa qual o campo (dentro dos elementos da lista) que será utilizado como chave para comparação. Neste caso, o segundo campo (prioridade);
    5. Os elementos do mapa são impressos, novamente utilizando a sintaxe de "List Comprehensions";
  • A sintaxe do Groovy é tão interessante quanto a do Python:
    1. Como em Groovy, listas e mapas estão entre [], um mapa, para ser inicializado vazio deve receber [:];
    2. Groovy, assim como Ruby, utiliza clousures, que lembram as funções anônimas do Java em termos de funcionalidade. Na linha linguagens.each{ algumacoisa } o código algumacoisa será executado para cada elemento da lista. Em nosso código, o mapa será populado com cada elemento (it) da lista e um valor randômico para a prioridade;
    3. Os elementos do mapa são ordenados através da clousure passada para sort. a e b são parâmetros passados pelo sort para a clousure. Indicamos então que a comparação destes elementos deve ser realizada pelo atributo value. O operador <=> equivale a escrevermos a.value.compareTo(b.value). Como não precisamos especificar um return, o valor desta expressão será retornado para a função sort. Cada clousure retorna o próprio objeto. Sendo assim, o método each pode então ser chamado e recebendo outra clousure que imprime cada um dos elementos do mapa (k=key, v=value).

E, por fim, a implementação do último requisito (7):

Em Java:

String fn = "Teste.java";
System.out.printf("\nPrimeiras cinco linhas de %s:\n", fn);
BufferedReader br = new BufferedReader(new FileReader(fn));
try {
 int i = 0;
 String line;
 while ((line = br.readLine()) != null && i++ < 5)
     System.out.println(i + ": " + line);
} finally {
 br.close();
}

Em Python:

fn = 'Teste.py'
with open(fn, 'r') as f:
 print 'Primeiras cinco linhas de %s:' % fn
 i = 0
 for line in f:
     i += 1
     if i > 5: break
     print "%s: %s" % (i, line[:-1])

E em Groovy:

def fn = 'Teste.groovy'
println "\nPrimeiras cinco linhas de ${fn}:"
File f = new File(fn)
f.withReader{ reader ->
 i = 0
 for (line in reader.iterator()) {
     println "${++i}: $line"
     if (i == 5) break
 }
}

Novamente, meus comentários:

  • Python utiliza um iterator implicitamente na navegação das linhas do arquivo. Mas, no meu entendimento, um programador Java faz um bom trabalho com o uso método readLine de BufferedReader.
  • Tanto em Java, quanto em Python, o uso do bloco finally é utilizado para garantir o fechamento de um arquivo, caso ocorra alguma exceção durante o processamento do arquivo aberto. Mas, do Python 2.5 em diante, é possível utilizar a palavra chave with, que simplifica a escrita da linguagem e, garante o fechamento do arquivo, automaticamente, na saída do bloco ou na ocorrência de uma exceção.
  • O versão Groovy do programa, passa uma clousure para o método withReader que, após a execução da clousure, fecha o arquivo, automaticamente.
  • Sendo assim, tanto o Python, quanto o Groovy, tem recursos de linguagem que auxiliam o programador a não se esquecer de liberar recursos, coisa que não ocorre no Java de maneira tão natural.

Baixe o código completo da versão Java, Python e Groovy deste programa.

Concluo este post, deixando a seguinte mensagem: Vá além do Java! Se você deseja ou precisa utilizar a plataforma Java, explore linguagens alternativas para ela, como o Groovy, o Jython, o JRuby ou o Rhino. Você só tem a ganhar com isto.

10 comentários:

  1. Excelente, Paulo. Eu mesmo comecei a colocar o pé no Python apenas recentemente e me arrependo de não ter começado a fazê-lo desde antes.

    ResponderExcluir
  2. Pj,

    Quem sabe, no futuro, o Java será considerado como o .Net, ou seja, uma plataforma?

    ResponderExcluir
  3. Como sou o "amigo" citado no primeiro § e, como minhas observações foram deturpadas pelo autor em prol de seu interesse em firmar seu ponto de vista, faz-se necessário esclarecer alguns pontos: Sou Gerente de Projetos há mais de 20 anos e posso afirmar que essa linha de raciocínio é antiga: surge algo "novo" e logo alguém quer implementar soluções com essa "novidade". Não sou contra novidades, pelo contrário, o que é impraticável é alguém tomar a decisão individual de adotar uma outra ferramenta de desenvolvimento em um ambiente onde não há "cultura" nessa novidade. Já aconteceu comigo de ter soluções adotando essa abordagem, a(s) pessoa(s) que desenvolveu(ram) sai(em) da equipe e nenhum dos outros membros têm conhecimento para manter / evoluir com o que foi implementado. Já estive em projetos em que essa abordagem levou a uma verdadeira Babel de linguagens, impossível de gerenciar. Minha opinião foi a de que é possível conciliar a adoção de novas soluções sem romper com a cultura estabelecida, a menos que a manutenção dessa base de conhecimento já adquirido pela equipe se torne de fato obsoleta. Iniciei minha vida profissional usando COBOL e FORTRAN, muitos hoje nem sabem mais o que é isso e chamam de "dinossauros" quem ainda utiliza essas linguagens. Contudo, na prática vários sistema importantes de grandes empresas ainda estão escritos com elas. Quem sabia COBOL no final dos anos 90, ganhou muito dinheiro por conta do bug do milênio. Grandes corporações não trocam seus sistemas críticos ao sabor das novidades. Ainda existe mercado para desenvolvedores COBOL, ou seja, nem COBOL está obsoleto ainda. Contudo tornou-se senso comum que ele não é mais adequado para atender as demandas atuais dos usuários de software, é preciso mudar! Com muito custo e cuidado elas vem adotando o uso de Java para migrar seus sistemas. Poderiam ter migrado para Pyton, Ruby, etc? Sim, mas não o fizeram pois à época ou não era possível atender as necessidades desses sistemas com elas ou elas eram demasiadamente incipientes e pouco testadas. Se o Java não evoluísse, concordaria em se iniciar um movimento de migração (altamente custoso), mas para quem acompanha, vê que pelo que está definido nas especificações da chamada JEE 6, inúmeras melhorias e simplificações ocorrerão, não há porque adotar uma linguagem/tecnologia diferente para cada problema existente, não porque JAVA não resolve, mas porque "dá mais trabalho em JAVA". Java hoje é uma gigantesca composição de frameworks, não apenas uma linguagem, é uma plataforma. Essa falácia da "facilidade de desenvolvimento" se perde nos anos de manutenção que estão porvir. Minha postura não seria diferente se uma empresa tivesse optado por adotar Ruby, já tem um enorme legado nessa tecnologia e aparecesse alguém dizendo para implementar soluções em outras tecnologias, sendo perfeitamente possível de implementar em Ruby, apenas porque na outra seria "mais simples" e "mais rápido". Como fica a manutenção? Como integrar essas peças? Como manter equipes com conhecimento tão diversificado? Para quem já gerenciou um projeto um pouco maior que criar um blog, sabe perfeitamente do que eu estou falando. Além disso, existem linguagens de script baseadas em java e que geram bytecodes que rodam em uma JVM qualquer. Acho que Groovy é um caminho natural para quem desenvolve em Java, embora bem diferente, mantêm uma linha comum e é fácil de integrar com o que já existe. É até possível prototipar em Groovy e a posteriori converter a classe groovy para JAVA. Logo, para quem já tem uma cultura estabelecida em Java, porque optar por algumas implementações em Python, Ruby, Perl, etc, se pode usar groovy? O argumento da aparente maior facilidade não é suficiente. É bom que fique claro o contexto em que faço essa observação. É obvio que se estou fazendo um freela para algum cliente e quero experimentar uma novidade, por que não? Mas em um ambiente onde há uma cultura previamente estabelecida, o buraco é mais embaixo.

    ResponderExcluir
  4. André,

    Java já é uma plataforma, muito antes do .Net da Microsoft. As linguagens que citei no post (Groovy, Python, JavaScript), são todas linguagens que rodam no Java (PLATAFORMA). Leia um pouco mais sobre isto em http://en.wikipedia.org/wiki/Java_Platform#Languages e também em http://www.is-research.de/info/vmlanguages/. Java também é considerado uma plataforma, por rodar sob várias tipos de hardware e sistemas operacionais. Na minha opinião, .Net nasceu como uma tentativa da MS de acompanhar esta característica. Meu conhecimento em .Net é limitado, mas até aonde eu já havia lido a respeito, esta plataforma da MS tinha apenas sido portado para o Linux (com o projeto Mono). Talvez isto tenha mudado, procure saber, e me diga!

    ResponderExcluir
  5. Gilson,

    Como lhe disse pessoalmente, eu fiquei extremamente contente por você ter respondido meu post! Agora eu posso explicar melhor o que conversamos e que você parece não ter entendido (e foi isto que motivou o meu post, OBRIGADO!). Meu trabalho atual está relacionado com a automação de alguns scripts que devem integrar o Subversion, a rotinas do sistema operacional Linux. Para que eu deveria utilizar Java para tarefas como esta? No Linux, eu já tenho o Python instalado pois grande parte das ferramentas que estão neste S.O. dependem dele. Python roda muito rápido ali, e está extremamente casado com o S.O. Não faria o menor sentido eu instalar uma JVM em algumas máquinas apenas para seguir um padrão corporativo da empresa que adota Java em suas SOLUÇÕES WEB. Entende o que digo? Estou muito contente e satisfeito pela empresa utilizar JBoss como servidor de aplicações, JBoss Seam como framework para desenvolvimento Web, COBOL para Mainframe e Bash para a automação de algumas atividades Linux. Ou seja, as coisas estão todas em seus lugares! Mas, não vejo nenhum sentido adotar o Java como solução para o problema que estou passando. Para fazer isto, meus colegas de setor, que teriam que dar manutenção no projeto, precisariam aprender Java e eu teria que instalá-lo no Linux em máquinas que não rodam JBoss e não tem necessidade alguma de uma JVM. O que você acha mais caro: eles aprenderem Java ou Python para tentarem me ajudar na construção destas aplicações? E mais, o que você acha que se aplica melhor a solução deste problema? Utilizando Python, eu tenho acesso a bibliotecas das aplicações que eu precisaria me integrar, diretamente. O mesmo não ocorre em Java, a não ser que eu utilize JNI. Compensaria tornar administradores de sistema que precisam automatizar algumas coisas, desenvolvedores Java, para que eles pudessem desempenhar suas atividades? Este é o ponto.

    ResponderExcluir
  6. Vejo muitas pessoas falando em facilidades de groovy, python e ruby, mas sempre faltam mencionar a IDE, pois para mim a IDE é responsável por boa parte da produtividade, e quem diz que programar em um text editor consegue ser tão produtivo quanto, é porque nunca utilizou o eclipse ou netbeans.

    Hoje não uso Java por ser uma linguagem completa uso porque atrelado a ides muito boas, tenho um conjunto ótimo de ferramentas e frameworks.

    No dia que groovy ou ruby tiverem ides iguais as de Java não hesitarei em trocar de linguagem principal, até lá permaneço com Java mesmo.

    ResponderExcluir
  7. Oziel,

    Grato pelo comentário. Mas, tanto Groovy, quanto JRuby possuem excelentes plugins para o Eclispe e para o NetBeans. Eu vou escrever um post sobre isto em breve quando for explicar como monto meu ambiente Ubuntu com ferramentas Java, utilizando scripts bash para automatizar este processo. De qualquer forma, procure se informar a melhor!

    []s,

    PJ

    ResponderExcluir
  8. Paulo,

    Eu tenho conhecimento sobre os plugins para o eclipse e netbeans, já usei os dois(groovy e ruby) para o netbeans e o de groovy para o eclipse, no entanto, comparado ao editor de código de java em ambas ferramentas, achei que os plugins ficavam devendo.

    ResponderExcluir
  9. Oziel,

    Eu ultimamente tenho programado mais em Bash e Python utilizando o Vim do que utilizando o Eclipse com qualquer outra linguagem. E sinceramente, não venho sentindo falta de um IDE para isto, como sentia no caso da codificação de aplicações Java envolvendo uma parafernalha de frameworks. Eu trabalho com TDD ou BDD em meus projetos e isto me facilita muito a busca de qualquer problema que eu possa encontrar em tempo de execução devido a algum erro (pouco comum) que eu possa cometer sem o uso da tipagem estática. Eu vejo que linguagens dinâmicas como Ruby, Groovy, Python simplesmente não precisam de IDEs pesadões e cheios de recursos para lhe dar produtividade. Mesmo assim, da mesma forma que você, muita gente não troca de linguagem em função dela não ter um bom IDE. Veja esta discussão sobre o suporte para o Groovy em IDEs no JavaLobby: http://bit.ly/4Xb5Q. Mas, para mim, como disse, isto não tem feito muita diferença. Trabalhando com Django por exemplo, ocorrendo algum erro na execução de um código Python, corrijo isto rapidamente com o Vim mesmo. Além do framework indicar de maneira clara o erro, o Python é simples e a linguagem me faz enchergar a solução do problema muito rapidamente. Eu também tenho utilizado o Groovy por exemplo, para escrever scripts de builds para aplicações Java e posso dizer que o suporte do Eclipse para isto, no meu caso, tem sido suficiente e satisfatório. E, mesmo sem ele, ainda consigo ser produtivo no Groovy, codificando num editor de textos simples como o Vim. Entretanto, sei que esta é uma tarefa mais complicada e propícia a erros do que utilizando um IDE. Só que eu tenho me virado bem sem eles. Tenho fugido de frameworks e IDEs grandalhões que tentam resolver todos os problemas do mundo. Gosto de simplicidade e praticidade e, definitivamente, estou muito contente que existam linguagens mais ágeis para a plataforma Java. E realmente não preciso ficar perdendo meu tempo aguardando um IDE suportá-las para sim, utilizá-las. Scala está aí... E também é uma excelente linguagem para você aproveitar o legado Java, se precisar dele. Eu não tenho a mínima idéia de como é o suporte do Eclipse para esta linguagem (http://bit.ly/WN8WO). Mas isto realmente não me importa pois sei que a linguagem realmente me ajuda a trabalhar melhor e mais rápido. Se o IDE ajuda ainda mais, melhor ainda! E tenho mais uma dica para você: se você quer um IDE que parece ter um suporte melhor a (J)Ruby e a Groovy, porque não experimenta também o IntelliJ Idea (http://bit.ly/11jYpP)?

    ResponderExcluir
  10. Eu trabalhei com Ruby on Rails durante seis meses, e testei JRuby on Rails com o Netbeans posso dizer que está cada vez melhor!
    A implementação de JRuby para plataforma Java com certeza deixa muito pouco(ou nada) a desejar em relação à do Matz(MRI), e o Netbeans está muito bom
    com o Suporte ao JRuby. Mas como bom filho, minha preferência ainda é pela linguagem Java, rsrs!
    Ótimo artigo PJ!
    []s

    ResponderExcluir