hisham hm

Comparando linguagens

Comparar linguagens de programação, seja discutindo na boa seus méritos e defeitos ou se digladiando em guerras santas do tipo “a ‘minha’ é melhor do que a ’sua’”, é um dos esportes preferidos da galera de informática em geral. Sendo pesquisador justamente da área de linguagens de programação, eu obviamente sou cheio de opiniões a respeito, mas eu evito entrar nos bate-bocas, que costumam ser sempre cansativos e repetitivos (ah, como eu mudei).

Esses dias, porém, li e ouvi alguns comentários que me deram vontade de dar um meta-pitaco no assunto. Dois alunos meus em sala de aula:

– Semestre passado o professor mandou fazer um trabalho de implementação, só que tinha que ser em Lisp.
– Lisp? O que é isso?
– Uma linguagem de programação lá, que o professor disse que era “melhor”.

Não sei se o tal professor disse isso, ou se foi a interpretação do aluno. Mas infelizmente comentários assim são muito comuns, ainda que não faça sentido considerar uma linguagem “melhor” em termos absolutos (melhor do que o que?) ou mesmo em termos relativos de forma não-qualificada. Por mais “tosca” que seja a linguagem X, quase sempre há algum aspecto em que dá pra fazer alguma qualificação do tipo “X é melhor que Y… no aspecto Z”, mesmo que Z seja algum aspecto menos técnico, como “é mais fácil de achar programadores pra contratar” — talvez no frigir dos ovos esse aspecto seja decisivo no negócio. Porém, dá pra argumentar também que nesse caso, não se está comparando as linguagens, mas sim o mercado de trabalho.

E é aí que eu quero chegar. O problema das discussões comparando linguagens é que em boa parte delas, não se está comparando as linguagens em si.

Comparar linguagens é, em primeiro lugar, comparar a especificação da linguagem. Sistema de tipos, estruturas de controle, sintaxe, semântica, biblioteca padrão, APIs para o mundo exterior. No nível mais fundamental, uma linguagem de programação é isso. Claro que isso não é a história completa, mas eu quero fazer um contraste do “resto todo” com a discussão sobre as “linguagens em si”.

Essa não é a história completa porque há muitos outros aspectos que acabam entrando em discussões sobre linguagens, de uma forma meio misturada. Pra citar alguns:

Desempenho - quando se fala de performance, não se está falando das linguagens, mas das suas implementações. Sem contar no “detalhe” de que algumas implementações são mais rápidas que outras em alguns aspectos e piores em outros. Nesse aspecto, o Benchmarks Game é particularmente incompleto porque eles arbitrariamente decidiram incluir só uma implementação de cada linguagem (quando ele ainda se chamava “Computer Language Shootout” tinha várias). Então, se alguém diz “PHP é mais rápido que Python”, está falando da implementação default, CPython? Ou da otimizada, PyPy? Tem uma boa diferença (e o Benchmarks Game usa a mais lenta). E PHP? A implementação original ou o HipHop, o tradutor pra C++ criado pelo Facebook? E estes não são os únicos.

E a linguagem em si? Ainda assim, em vários casos o design da linguagem em si afeta sim a performance que se consegue tirar das implementações: é um dos motivos pelo qual a implementação do tracing compiler de Lua (LuaJIT) tende a ser mais rápida do que a de JavaScript (V8) — a linguagem é menor e mais facilmente otimizável. Evidência disso é que a Mozilla definiu um subset de JS, asm.js, para ser uma implementação voltada a alto desempenho.

Ecossistema - linguagens não existem no limbo, então o suporte em volta é importante: bibliotecas, ferramentas de build, gerenciadores de pacotes, debuggers, IDEs (pra quem gosta), etc. Botei isso tudo sob o guarda-chuva de “ecossistema”, mas certamente esses itens são bem diferentes entre si e têm impactos diferentes (botei eles mais ou menos em ordem de importância pro meu gosto pessoal). Note que eu diferencio as bibliotecas padrão (que eu citei lá em cima na “linguagem em si”) das bibliotecas extras. Essas últimas são uma decisão de design do seu projeto; das primeiras não tem como fugir.

E a linguagem em si? Isso tudo é importante e afeta a produtividade de quem programa, claro. Mas, como no caso do desempenho, há uma diferença fundamental de discutir as linguagens em si: todas essas peças do ecossistema são trocáveis e a linguagem continua sendo a mesma. Você troca do Make pro CMake, mas C++ ainda é C++. Você troca de JQuery para Underscore, mas JavaScript ainda é JavaScript. Você pode optar por usar ou não RubyGems ou o LuaRocks. (E sim, acredite se quiser, há quem programa em Java sem IDE. ;) )

Killer applications - eu poderia botar isso junto com o ecossistema, mas achei que merecia um item próprio. De certa forma, a história das linguagens de programação e suas comunidades é a história das suas killer applications. Não tem como pensar em Ruby sem pensar em Rails, não há como falar de Lua sem citar o seu sucesso na indústria de jogos, de C e não falar de coisas baixo-nível tipo Unix, e assim por diante. E sim, muita gente vai escolher uma linguagem por causa de um framework específico, ou porque ela é “a linguagem que todo mundo usa pra fazer tal coisa”.

E a linguagem em si? Bom, muitas dessas killer applications das linguagens se derivam do design delas, afinal muitas linguagens foram criadas pra fazer alguma coisa específica: todo mundo fala maravilhas da linguagem R para estatística porque afinal, ela foi feita pra isso (e por consequência hoje tem milhares de bibliotecas prontas para estatística). Em outros casos, é quase uma casualidade: Python e Ruby são similares o suficiente para que o Rails pudesse ter sido criado em Python, e de fato hoje não faltam frameworks em outras linguagens que são de certa forma clones “de espírito” do Ruby on Rails.

“JavaScript” vs. “JavaScript: The Good Parts”: enough said.

Nesses casos, o que resta, além de diferenças menores de design dos frameworks (que, sendo, parte do ecossistema, sempre podem ser trocados), são as diferenças fundamentais das linguagens em si. E quão importantes essas diferenças são, já que a (bem) grosso modo dá pra implementar qualquer coisa em qualquer linguagem? São muito. Coisas como a sintaxe, sistemas de tipos, gerência de memória, são diretamente ligadas aos tipos de bugs que a gente tende a produzir quando programa. Você pode arranjar a melhor IDE, o melhor debugger, usar as melhores bibilotecas e frameworks, e ainda vai ser mordido vez que outra por regras de conversão de tipos bizarras. Como disse o Roberto esses dias, você pode ser a pessoa mais cuidadosa do mundo com todos os cantos escuros da linguagem e escolher um “subset seguro” pra trabalhar, mas quando você tiver que dar manutenção do código de outra pessoa (seja colega de trabalho ou código de alguma biblioteca), diga adeus ao “subset seguro”. O resto todo em volta tem jeito — troca-se a VM por uma mais rápida, troca-se a biblioteca por uma mais elegante — mas não há como fugir dos problemas da linguagem em si.

É por isso que PHP e JavaScript, mesmo com os melhores compiladores e as melhores bibliotecas do mundo, ainda vão ser linguagens “toscas”. Por outro lado, linguagens funcionais como Haskell (ou Lisp!), mesmo com toda a sua elegância conceitual, não são linguagens populares, em parte porque falta a elas toda a infraestrutura em volta pra serem uma opção pragmática. Felizmente, porém, o mundo não é feito só desses dois extremos. A gente tem que lembrar que a linguagem é o meio para um fim e que a linguagem que a gente programa não é o nosso time do coração no qual morreremos abraçados. Esses dias mesmo falei para um amigo que eu acho que ele não deve focar em se especializar pra ser um “programador Java” ou um “programador Python”, mas simplesmente um bom programador, e que essa polivalência acabaria rendendo mais em longo prazo. As lições mais importantes que a gente aprende nessa vida de programação se aplicam a todas as linguagens, e como nas linguagens naturais, quanto mais linguagens a gente aprende, mais fácil é aprender uma próxima. (Aliás, aprender uma nova linguagem é uma das melhores maneiras de se “reciclar” mentalmente.)

Moral da história: escolha a linguagem que resolve o seu problema, mas tendo a opção, escolha uma linguagem decente!


  1. Thiago Varela

    Wednesday, May 29, 2013 - 18:29:49

    Belo post!
    Só que agora eu vou ter que perguntar: o que é, pra ti, “uma linguagem decente”? Dá o teu parecer aí! :)

  2. Etiene

    Thursday, May 30, 2013 - 08:39:39

    Pelo visto qq coisa q seja melhor q javascript e php :P

  3. hisham

    Friday, May 31, 2013 - 00:53:28

    Boa e difícil pergunta! É muito uma questão de gosto, sem dúvida. No meu gosto, “linguagens decentes” são as que têm consistência de sintaxe e semântica, e onde a gente tende a escrever programas com menos bugs com mais facilidade. Tendem a ser linguagens que tu vê que quem fez entende da teoria por trás e também tem um senso de aplicação prática.

    Eu tenho elogios e críticas pra fazer a praticamente todas as linguagens com que eu tive contato, mas certamente gosto de umas mais do que de outras. Vejamos… no mundo das “linguagens de scripting com bibliotecas padrão faz-tudo” (Perl, Python, Ruby, PHP) eu tendo a gostar mais de Python, mas quando precisei fazer trequinhos quick-and-dirty pra web acabei fazendo em PHP (que eu sei bem pouco) porque (a) o ambiente já vinha todo pronto no servidor e (b) é uma linguagem que dá pra sair programando sem “aprender direito”. Esse último ponto também é um contra, porque é tão ou mais fácil escrever código tosco do que código decente — em outras linguagens, programando toscamente o código nem roda (vide C). Eu sou obviamente biased, mas Lua é uma linguagem bastante consistente (mas claro que tenho críticas também)… só que ela não tem o arcabouço pronto de bibliotecas então acaba ficando pra nichos diferentes de Python e cia. Dessas, Perl é uma bizarrice (mas que chega a ser quase interessante, tipo um monstrinho esquisito), Ruby eu acho meio infeliz (um meio-termo entre Perl e Python com uma comunidade de programadores que amam coisas como “duck typing” e “monkey patching” (argh)), Python é legalzinho mas seria mais legal pra scripts pequenos do que pra programming-in-the-large, e PHP é uma aberração de design que dá pra programar de olhos fechados.

    Pra escrever coisas como o htop, sinceramente, eu não tinha outra escolha a não ser fazer em C. Não porque é a melhor linguagem pra tarefa. Longe disso: C é baixo-nível demais pra escrever uma aplicação como htop — já tive inúmeros crashes bizarros que eu jamais deveria ter tido. Só que pra escrever uma aplicação de terminal que eu possa chegar em qualquer máquina Linux, compilar e sair usando, só fazendo em C ou C++. (E sinceramente, C++ está muito abaixo de C na minha escala de decência — C++ é um monstro e o melhor exemplo da farsa do discurso do “subset seguro”). Eu acabei pegando afeição por C com o passar dos anos, mas acho que é um pouco de Síndrome de Estocolmo.

    Podem rir, mas uma linguagem que eu acho super direitinha pra programação de aplicações é Pascal. Infelizmente, programar em Pascal hoje é pedir pra se incomodar com a infraestrutura. Não programo em Pascal desde a graduação. Se o htop fosse escrito em Pascal definitivamente não seria tão difundido porque ajeitar o sistema de build seria um stress a mais pros possíveis usuários e não ia se popularizar ao ponto de entrar nos repositórios das distros. Idem se fosse em Haskell, Eiffel ou o que fosse. Esse é um empecilho clássico pra qualquer linguagem ganhar espaço.

    Go parece ser uma linguagem que quer ocupar o espaço de C, mas do pouco que eu vi eu gostei de umas coisas e não gostei de outras e nunca programei. Mas parece bem pensada. É da mesma galera ex-Bell-Labs que criou Unix, C e cia. Numa cadeira do mestrado fiz um trabalho em Limbo, dessa mesma galera, que usa conceitos que reapareceram em Go e eram bem interessantes. Tudo muito legal, mas na época de interesse mais acadêmico do que prático. Go quer ser a versão prática, vamos ver se pega tração. Se entrasse por default no GCC seria um grande passo.

    As linguagens funcionais (Lisp, Racket, Haskell, Ocaml) são definitivamente decentes, conceitualmente falando. O problema pra mim é que programar nelas me demanda um nó na cabeça que eu até hoje não consegui desatar. O grande Edsger Dijkstra disse uma vez que “programadores que aprenderam a programar usando BASIC têm um dano cerebral que é irreparável”. Eu me enquadro nessa categoria. ;) Falando em BASIC, Visual Basic era outro típico exemplo de “linguagem tosca”, mas ouvi dizer que da versão .NET pra cá deram uma “consertada” — leia-se, jogaram fora a linguagem antiga e agora VB.NET é basicamente C# disfarçado com outra sintaxe. Mas nunca usei VB.NET pra confirmar isso; VB antigo com certeza era uma bagunça.

    Uma linguagem com que eu tenho uma relação estranha é Java. Eu acho ela underrated pelo pessoal acadêmico e overrated pelo pessoal da indústria. Quero distância dos mega-frameworks-enterprise Java que quando dão pau geram stack traces com literalmente 70 níveis de profundidade. Por outro lado, se tu não olhar para a biblioteca mas para a definição da linguagem (tipos, variáveis, estruturas de controle), Java é uma linguagem OO razoavelmente pequena (ie, “cabe na cabeça” ao contrário de C++) que te permite focar no problema. O chato é que os idiomas consagrados (ie, o que é considerado o “jeito certo” de programar) são extremamente burocráticos e a API padrão idem, o que torna programar em Java invariavelmente “chato”. O que por um lado é bom, porque ninguém quer que o seu trabalho seja um filme de suspense quando se tem prazo pra entregar, mas por outro lado é… chato.

    Resumindo, todas as linguagens têm seus problemas e a visão que a gente tem é muito influenciada pela experiência sempre limitada que a gente tem. Se eu continuar escrevendo sobre o que eu acho de cada linguagem, acabaria contando basicamente a história da minha vida aqui. Mas basicamente, as linguagens que eu gosto (1) me passam um senso de design consistente, (2) não são cheias de pitfalls que me fazem ficar caçando bugzinhos na execução do programa ao invés de gastar tempo no design da solução do meu problema, e (3) resultam em código cujo próprio texto descreve o design da minha solução (e sim, isso é mais fácil de fazer em algumas linguagens do que em outras).

Add comment

Fill out the form below to add your own comments.

CAPTCHA imageReload imageAudible version of CAPTCHA-image