Ferramentas do usuário

Ferramentas do site


prog:qual-ambiente-escolher

Qual ambiente de programação escolher?

Por vezes no canal #mundo-libre do Servidor IRC do Slackjeff se iniciou a discussão sobre qual ou quais linguagens e ambientes de desenvolvimento de software seriam mais interessantes para aprender. Muitas pessoas chegam ao canal com uma sede de conhecimento (que particularmente considero louvável), mas sem uma clareza de qual conhecimento priorizar. Evidentemente, não há uma resposta pronta para esta questão. Uma linguagem adequada para uma situação pode não ser boa para outra, assim como diferentes implementações de uma mesma linguagem poderão ser voltadas para usos diferentes. Facilmente você se perderá nas escolhas, se pensar que há uma única solução universal para todos os problemas.

Porém desconfio de que no fundo não é uma resposta pronta que você busca, mas sim algumas dicas sobre como pode chegar a essa resposta por conta própria. Este artigo é uma tentativa (espero que bem sucedida) de guiar o leitor a não apenas uma, mas a várias decisões satisfatórias, cada qual para as situações e desafios que se apresentarem. Para isto, vamos discutir alguns princípios básicos.

A informação é abundante, mas a atenção é escassa

Você talvez tenha ouvido falar que uma linguagem em particular seja o máximo e que ela fará de você um novo astro da programação. Bem, eu detesto dizer isso, mas dificilmente uma afirmação desse tipo será verdadeira. Talvez, tenha ouvido uma versão mais chata e desanimadora desse tipo de afirmação, que é a de que uma linguagem específica lhe garantirá mais oportunidades de emprego. Essa afirmação pode até ser verdadeira em alguns momentos, mas costuma ser cheia de armadilhas, pois isso diz muito pouco sobre a situação futura das oportunidades para essa mesma linguagem, e muitas vezes está associada a empregos precários e mercados saturados de profissionais que ouviram a mesma história e cegamente resolveram tentar a sorte.

Talvez esses dois tipos problemáticos de afirmação sejam a gênese de uma maneira um tanto equivocada de pensar a programação que é a de que há uma única solução para tudo, na qual você deverá investir todo o seu tempo e energia. Dada uma importância tão grande a essa decisão, naturalmente a sua angústia e medo de tomar a decisão errada também serão grandes. Mas não precisa e não deve ser assim. Perceba que a origem dessa angústia está no fato de que aprender qualquer coisa requer tempo e esforço, os quais você não quer desperdiçar. Embora a quantidade de informação disponível sobre vários desses assuntos seja abundante, a atenção é um recurso escasso, o qual você, talvez até sem perceber, valoriza muito. E faz bem, é um recurso valioso mesmo.

O problema está em pensar que uma única linguagem ou implementação merece toda a sua atenção, e todo o resto merece zero da sua atenção. Mais do que isso, o problema está em comprar, sem questionar, essa ideia de que uma linguagem é o máximo ou fruto da sua salvação profissional. Essas ideias dificilmente chegarão a você por acaso. Elas são parte de um complexo jogo de forças conflitantes e nebulosas entre empresas que contratam programadores, empresas que fornecem ferramental para desenvolvimento, programadores em busca de fama e fortuna, órgãos reguladores e diversos outros atores, cada qual defendendo seu quinhão. É no meio desse tiroteio que você está tentando se decidir sobre o que aprender, e no meio de um tiroteio a única decisão que cabe tomar é sobreviver e sair do meio dele.

Somente então, com a devida distância de fatores externos você conseguirá refletir sobre quais conhecimentos deve priorizar. Lembre-se: cada escolha é uma renúncia, pois para cada instante gasto em um sentido, você estará abrindo mão de inúmeras outras possibilidades de uso desse mesmo instante. Portanto, saiba como direcionar seu tempo a algo que valha à pena para você, não para terceiros que queiram especular sobre a sua escassa atenção. Que eles se resolvam com o tempo deles, pois o seu é seu. Então não caia na armadilha de comprar esses discursos, para início de conversa.

Ainda assim, faço um alerta, que até serve para aliviar essa angústia que mencionei: errar é parte do processo, e é comum que nos seus primeiros passos você “desperdice” algum tempo. Na prática porém, nem é possível dizer que isso é desperdício, pois não temos bola de cristal para adivinhar o que nos será útil no futuro, e todos esses erros nos ensinarão alguma coisa. Dito isso, por um lado tenha o cuidado de não ser erroneamente direcionado a algo que não lhe interessa, mas por outro não fique paranóico(a) ao ponto de achar que precisa acertar todos os seus passos. Você não tem essa obrigação.

Como dialogar com as máquinas

Muito bem, agora você abriu a sua mente para todas as possibilidades de aprendizado, e decidiu tomar uma decisão não contaminada por discursos simplistas, que não lhe convém. Isso é um grande passo, mas ainda assim, essas possibilidades são muitas. Como resolver isto? Para começar, precisamos eliminar uma outra confusão, que diz respeito a linguagens e implementações. Talvez você já tenha se deparado com os termos “linguagem compilada” e “linguagem interpretada”. Tratam-se de termos não muito corretos pois uma linguagem de programação, antes de mais nada, é apenas uma linguagem e isso tem pouca relação com o modo como ela será traduzida para linguagem de máquina, ou seja, instruções em forma de dígitos binários (bits), que controlarão o dispositivo utilizado.

Essa estratégia de tradução pode variar significativamente para uma mesma linguagem, de modo que ela pode ser interpretada ou compilada, a depender da implementação utilizada. Evidentemente, algumas linguagens são pensadas especificamente para uma estratégia, não sendo muito adequadas para outras. Seja como for, linguagens tem uma relação mais forte com a arquitetura lógica dos programas, ou seja, como interpretar e conectar ideias. Implementações, por outro lado, tem relação mais forte com a arquitetura física, ou seja, como traduzir essas ideias para bits, que por sua vez terão uma representação física, como impulsos elétricos ou ondas eletromagnéticas, por exemplo (varia conforme o meio de transmissão e armazenamento desses bits).

Então vamos detalhar um pouco mais o que as implementações fazem. No processo conhecido como compilação (que a rigor ainda pode ser subdividido em algumas tarefas), o código-fonte é convertido para bits em sua integralidade, previamente à execução do programa. No processo de interpretação, por outro lado, os comandos do programa são traduzidos dinamicamente, isto é, enquanto o programa está em execução. A interpretação tende a ser mais lenta, e a depender do tipo de tarefa a ser executada, essa diferença de desempenho pode ser imperceptível ou absolutamente inviabilizadora. Ainda uma terceira estratégia relativamente comum é chamada de compilação em tempo de execução (compilação JIT, na singla em inglês, Just In Time), na qual partes do programa são compiladas enquanto ele executa, aproveitando algumas estatísticas coletadas durante a execução.

Tipicamente, linguagens de mais baixo nível (isto é, que proveem menos camadas de abstração entre a linguagem de programação e instruções binárias) são usadas em implementações que recorrem à compilação, porém não há uma regra explícita sobre isso. Outro fato que merece destaque é o de que é muito comum que uma linguagem possua várias implementações diferentes, cada qual com um objetivo em particular. Isto pode ocorrer, por exemplo, quando uma implementação compila o código, enquanto outra interpreta, e assim essas implementações seriam úteis em situações diferentes.

Escolher uma linguagem e uma implementação depende muito do que você planeja fazer, em primeiro lugar. Então, primeiro de tudo, você precisa compreender quais são as premissas e restrições em jogo, envolvendo requisitos de desempenho, segurança, manutenibilidade, compatibilidade, portabilidade, interoperabilidade e usabilidade. Saber tudo isso quando você tem um projeto bem definido pela frente já é uma tarefa complexa por si só, que dirá quando você não possui nenhum projeto no radar e apenas quer aprender a programar. Isto nos leva ao próximo tópico.

Aprender a programar é um projeto por si só

Quando você não tem um projeto em particular no momento, mas deseja programar, isso provavelmente significa que o seu projeto atual é aprender a programar. Na realidade, este é um projeto que nunca vai te abandonar (e isto é bom), mas por hora vamos tratá-lo como algo que tem início, meio e fim.

Algumas linguagens são particularmente interessantes para explorar as dinâmicas da informação e as possibilidades de construção de algoritmos e resolução de problemas, isto é, para o aprendizado da programação propriamente. Nem sempre elas serão adequadas para resolver um problema prático, mas o seu aprendizado terá servido um importantíssimo propósito, que é aprender a programar. Isto se revertirá em benefícios para outros ambientes que vier a usar depois, justificando o tempo investido inicialmente nestas linguagens. Quanto menos recursos e mais simples for uma linguagem, mais ela forçará o programador a compreender essas dinâmicas e comparar diferentes maneiras de construir um algoritmo.

Ao mesmo tempo, algumas linguagens são também úteis para compreender como as máquinas interpretam e executam instruções, e como lidam com os dados que fazem parte do processo, o que é um conhecimento valioso para a programação. Na prática, porém, é importante lembrar que o principal fator a facilitar ou dificultar esse entendimento já não é tanto a linguagem em si, mas a implementação da linguagem. Quanto mais abstrações houver no caminho entre a linguagem usada pelo programador e a linguagem entendida pela máquina, menor tende a ser a compreensão dos resultados de uma maneira particular de construir o programa.

Perceba que aqui demonstro duas formas importantes de escassez que levam o programador a se aprimorar e aprender: a escassez de recursos sintáticos (portanto referente à linguagem de programação, propriamente), e a escassez de transformações entre o programa e o processo executado na máquina (portanto referente à implementação da linguagem). O tempo dedicado a linguagens destes dois tipos dificilmente poderia ser considerado um desperdício, pois darão uma base sólida para interpretar e conhecer novas linguagens, além de por si só já resolverem sim muitos problemas práticos.

Dito isso, você talvez pense que o processo de aprendizado possa ser tedioso, pois problemas puramente teóricos e pequenos programas triviais de fato não serão usados posteriormente. O único propósito de exercícios desse tipo é ensinar um conceito. Não ver o seu aprendizado podendo ser aplicado na prática pode mesmo ser bem frustrante, e certamente este é um fator que dificulta o aprendizado. Ao longo deste texto, vou mostrar algumas maneiras de lidar com isso, a começar pelo próximo tópico.

Programação é uma arte

Ao fazer da programação uma arte, ela fará de você um artista. E o que caracteriza um artista? É o toque pessoal, a maneira particular de se manifestar, por vezes inconfundível com a de outros artistas. Um artista não é uma peça substituível. Um artista se locupleta ao criar e ver sua criação, e se houver mais apreciadores da sua obra, tanto melhor (mas isto não é pré-requisito para a criação). E nesse caso particular de arte há uma fusão interessante de forma e função, na qual parte da beleza está na função. Portanto, um artista programador se sentirá motivado a criar programas que sejam melhores naquilo que fazem porque isso é parte da beleza da obra. Ora, a perspectiva de se encantar com seu próprio trabalho, se desenvolver com ele, ganhar uma particularidade e identidade em função disso não é animadora?

Vejamos a alternativa. Você apenas segue manuais, obedece cegamente regras que não compreende, trabalha como uma máquina, sem inspiração, sem ideias, você apenas segue instruções dogmáticas, e em função disso se torna uma peça substituível de um processo que não demonstra propósito algum. Parece bem chato, não? O que as pessoas tendem a fazer diante de uma tarefa chata? O mínimo possível. Entenda-se, algo inexpressivo e que tende a uma qualidade inferior ou medíocre, sem nada que chame a atenção ou diferencie. Este não é um resultado desejável.

Neste sentido, entenda que programar não é e não pode ser uma tarefa mecânica e monótona. É uma expressão autêntica da sua visão de mundo na forma de códigos que serão lidos pela máquina. Isto requer criatividade e pessoalidade. Encarar a programação desta maneira é uma forma também de se importar menos com o resultado final e se importar mais com o processo, o que ajuda a diminuir a angústia típica de quando se está estudando e quer já ver algum resultado prático.

Ainda assim, há limites para essa visão. Como comentei, há uma fusão entre forma e função, e portanto conseguir alguns pequenos resultados parciais ao longo do aprendizado será necessário. À medida que o aprendizado evolui, esses pequenos resultados vão se somando para formar algo maior. Tenha em mente que algumas linguagens oferecem mais benefícios no longo prazo, ensinando sobre conhecimento mais profundo da arte, enquanto outras possuem um valor maior naquilo que é mais imediato e precisa de um resultado mais rápido. Compreender essa variedade e saber usar isso também contribuirá para o seu processo de aprendizado.

Tipicamente, linguagens de script se encaixam mais no segundo caso, isto é, são uma boa maneira de praticar alguns conceitos aprendidos e já obter algum resultado mais imediato.

Fuja dos dogmas

Corroborando com a visão de que programção é uma arte, tenha um cuidado especial com visões muito dogmáticas sobre a programação. Toda regra deve existir por um motivo claro e bem embasado, que você consiga enxergar na prática.

Ao programar, jamais siga regras que você não compreende. Compreenda, questione quando não compreender, torture as regras até que elas confessem para que servem. E quando não servirem para nada, descarte-as. Quando for confrontado com a afirmação de que determinado método é o melhor, tente provar o contrário. Quando disserem que um método é ruim, tente provar o contrário. Seja do contra, o tira-teima será seu aliado na busca por algo que faça sentido para você. Algumas vezes você concluirá que a afirmação era verdadeira. Porém outras vezes, poderá perceber que não era.

Tenha um cuidado especial com linguagens que forçam demais uma maneira de fazer as coisas, em detrimento de outras. Quanto ao problema que mencionei sobre um processo de aprendizado tedioso e chato, a visão dogmática está no cerne deste problema. Resolver exercícios que você não compreende para que servirão ou como se relacionam com a prática é exatamente o que dificulta que o aprendiz se encante com a sua criação e assim tenha vontade de ir além. Dito isso, sempre procure compreender como um conceito aprendido se relaciona com problemas reais.

Onde? Quando? Como? Por quê?

Ao buscar uma linguagem para resolver um problema, busque alguns dados sobre ela primeiro. Em que contexto ela surgiu? Ela veio para resolver problemas reais? Que problemas eram esses? Seu desenvolvimento permaneceu nesse sentido até hoje? Que implementações ela possui? Quais são suas estratégias?

Essas perguntas não são difíceis de responder com uma breve pesquisa, e são altamente reveladoras. Compreender o contexto em que uma linguagem e suas implementações surgem ajuda a compreender em que cenários ela tende a ser mais eficaz. Ao longo do tempo essas linguagens vão evoluindo e podem ser adaptadas para novos cenários. Compreender as características de uma linguagem e de suas implementações que a fazem ideal para um contexto ajudará a entender se serão adequadas também para o seu contexto em particular.

Essas características dirão muito sobre os tipos de aplicações que se pretende construir. Existem diferentes arquétipos que você pode considerar para o seu programa, e a linguagem escolhida pode se encaixar melhor ou pior nesse arquétipo. O livro Structure and Interpretation of Computer Programs (vide referências) possui em seu preâmbulo uma interessante alegoria sobre programas que são construídos como pirâmides e programas que são construídos como organismos vivos.

Pirâmides são gigantescas estruturas, formadas por blocos pesados e muito difíceis de mover (pra não dizer impossíveis). Ao longo do tempo elas vão sofrendo mudanças, mas essas mudanças são pequenas e graduais, e leva muito tempo para que uma pirâmide mude significativamente o seu aspecto. É uma estrutura criada para durar. Organismos, por outro lado, sofrem diversas mutações ao longo da vida. Eles vão se adaptando conforme o meio onde vivem e assim garantem sua sobrevivência, ou perecem, quando não são capazes de fazê-lo. Perceba o caráter antagônico dos dois arquétipos aqui expostos: no primeiro a grande virtude é a rigidez, no segundo é a flexibilidade.

Como trazemos essa alegoria para o mundo da programação? Pense em programas que são feitos para manter o seu aspecto por longos períodos, mudando apenas o que é estritamente necessário. São programas no arquétipo de pirâmide. Um kernel (cerne) de um sistema operacional por exemplo, tipicamente não sofre mudanças radicais em pouco tempo. Ele precisa ser construído e mantido de forma que possa ser devidamente estudado e compreendido e seu comportamento precisa ser amplamente testado em equipamentos diferentes, gerenciando aplicações diferentes e sendo usado por públicos diferentes. Também poderíamos dizer algo parecido de um sistema tipográfico, que leva anos para chegar a um nível em que possa gerar documentos da mesma qualidade oferecida por equipamentos analógicos, e atingido esse ponto, não terá muito mais a mudar sem o risco de comprometer sua função principal.

Para o segundo arquétipo podemos pensar em algoritmos de inteligência artificial, que precisam tomar diferentes decisões com base em fatores muito dinâmicos, e que são gradualmente refinados com novos conjuntos de dados, dados que vão moldando dinamicamente esses algoritmos. Quanto mais difícil for a alteração dos programas, menor será sua capacidade de aperfeiçoamento, e portanto ele falhará na sua função principal, que é o aprendizado. Podemos pensar também em programas que são extensões de programas maiores, e que de algum modo alteram ou complementam a funcionalidade principal (tipicamente em um programa mais alinhado ao arquétipo de pirâmide). Para poupar o programa principal de alterações maiores e mais frequentes, as extensões cumprem esse papel de dar flexibilidade ao todo. Em alguns tipos de aplicação essa combinação é bem frequente, como em editores de texto, editores de imagem, jogos, entre outros.

Dito isso, espero que você perceba que a depender da natureza do problema a ser resolvido, você precisará fazer escolhas diferentes. Não acredite em uma única solução para tudo, pois os problemas que a computação pode ajudar a resolver são diversos demais para isso. É precisamente por isso que existem tantas linguagens e implementações diferentes, com características que se repetem entre elas, mas cujas combinações de características são praticamente únicas para cada. Essas combinações não são escolhidas ao acaso. Compreenda essa composição para então assimilar a sua função.

Faço um adendo específico para o processo de aprendizado, que idealmente contemplará um entendimento de diferentes cenários, e portanto será permeado pelos dois arquétipos mencionados. Como consequência disso, será permeado também por mais de um tipo de linguagem.

Custo técnico

Ao escolher uma linguagem, mais do que olhar para as benesses que ela pode oferecer, é preciso prestar atenção também ao custo técnico que ela impõe. Lembre-se: escolher é renunciar, do contrário não é uma escolha, senão um curso de ação óbvio. Você sempre estará abrindo mão de algo, mesmo que não saiba exatamente o quê. É preferível que saiba.

Muito bem, então primeiro vamos ponderar sobre o que é custo técnico. Para isto, observe primeiro o papel que a abstração tem em um ambiente computacional. Vamos traçar um paralelo com linguagens naturais, como português, por exemplo. Usamos palavras, frases, discursos, que são elementos abstratos. Eles nos permitem compreender o mundo e abordar as coisas em um plano virtual. Ao dizer, “chuva” imediatamente você poderá pensar na chuva, sem que ela efetivamente esteja ocorrendo nesse instante. Da mesma forma, os bits são uma abstração sobre a concretude dos dispositivos eletrônicos, que usam impulsos elétricos, capacitores e outros mecanismos físicos para armazenar e transmitir a informação, mas que por si só não dizem absolutamente nada.

Um bit pode significar qualquer coisa e nós é que atribuimos esse significado. Por exemplo, podemos convencionar que 0 seja “não” e 1 seja “sim”. Podemos convencionar que 00 seja “não”, 01 seja “provavelmente não”, 10 seja “provavelmente sim” e 11 seja “sim”. Podemos estabelecer diversas combinações de bits e atribuir significados, e isso efetivamente é o que nos permite programar as máquinas. Então mesmo a linguagem de máquina é uma abstração. Para além da linguagem de máquina, porém, definimos ainda novas abstrações sobre estas, para que programar uma máquina seja menos tedioso e propenso ao erro, e isso nos leva às diversas linguagens de programação existentes, cada qual em níveis de abstração diferentes. Quanto mais abstrato, mais dizemos que se trata de uma linguagem de alto nível.

Evidentemente, abstração tem um custo. Quanto mais abstração, maior esse custo. O que justifica esse custo maior? Linguagens de alto nível colocam à disposição do programador alguns mecanismos sintáticos que são traduzidos, via implementação da linguagem, para bits com algum significado atribuído. Isso alivia o programador de ter que se preocupar com os bits gerados, aumentando a sua produtividade. Mecanismos mais genéricos são, via de regra, menos intuitivos, e mecanismos mais específicos são mais intuitivos. Porém, quanto mais específicos forem, mais numerosos terão de ser, e maior complexidade introduzirão ao contexto da programação. Vale lembrar que uma linguagem com regras demais também acaba se tornando improdutiva, pois exige do programador memorizar essas regras e ponderar como elas interferirão no programa. Logo, temos um “intervalo ideal” entre abstração em linguagem de máquina e linguagem coloquial.

O posicionamento desse intervalo ideal varia conforme a situação. Algumas situações exigem certa austeridade, no sentido de uma linguagem mais escassa em recursos de abstração e portanto mais exigente com o programador na compreensão dos bits gerados. Geralmente isso ocorre ao programar para dispositivos embarcados, máquinas com capacidade limitada ou situações que tem desempenho como fator crítico. Outras situações exigirão uma capacidade de desenvolver rapidamente uma solução e/ou alterá-la com frequência, com pouco tempo para planejamento, e nesses casos, dispor de recursos prontos (pré-abstraídos) será de grande utilidade.

Seja qual for a posição desse intervalo, porém, você deve ter percebido que para qualquer cenário o termo “complexidade” ganha uma conotação negativa. Isto não é por acaso. A complexidade sempre afetará negativamente o programa. Infelizmente, porém, em algum nível ela sempre estará presente. A questão mais importante nesse quesito é evitar a complexidade desnecessária, e impor controle à complexidade inevitável. A complexidade é uma espécie de assombração. Seu papel não é destruí-la, pois isso é impossível, mas impedir que ela se imponha sobre os seus projetos. Ela sempre estará à espreita, aguardando uma oportunidade para que sua introdução seja justificada ou passe desapercebida. Seu papel é estabelecer fronteiras e vigiar para que ela não consiga se infiltrar no programa. Do contrário, o custo técnico crescerá exponencialmente, e em algum momento vai ficar inviável.

Por isso repito, ao escolher, preste bastante atenção ao custo técnico. Você pode achar que vai ganhar tempo com uma facilidade ou outra, mas pondere quanta complexidade essa facilidade pode introduzir ao programa ou ao processo de desenvolvimento do programa. No longo prazo, a complexidade adicionada poderá fazer com que você perca muito mais tempo do que ganhou.

Até aqui falamos em custo técnico em termos de desenvolvimento e manutenibilidade. Porém há um outro aspecto também importante que é o custo a partir de uma perspectiva das máquinas. O que é custo técnico para as máquinas? Nesse caso, temos o custo sob duas formas: tempo e espaço. O tempo é representado fisicamente pelo processador (ciclos de processamento), e o espaço é representado pela memória (bits armazenados). Compreender como os programas utilizam tempo e espaço em uma máquina é outra ponderação importante. Isso geralmente está relacionado ao modo como os algoritmos são construídos, porém a maneira de fazê-lo varia conforme as regras de cada linguagem e se manifestam de formas diferentes a depender das implementações escolhidas.

Eu sei que se preocupar com esses detalhes pode parecer algo chato, mas ofereço uma perspectiva diferente: veja por exemplo quão chatos e entendiantes podem parecer os semáforos e sinalizações de trânsito a primeira vista, e quão pior ainda é um trânsito sem eles para compreender o que quero dizer. Ao fim, essas restrições servem a um propósito mais do que justificado. Portanto pensar em eficiência, concisão, manutenibilidade, redução de complexidade e retrocompatibilidade não é gastar tempo com chatices, é usar essas placas e semáforos para evitar um pesadelo posterior.

Popularidade x Comunidade

Outra confusão comum que precisa ser tirada do caminho é entre a popularidade de uma linguagem e o quanto isso se traduz em colaboração e cooperação entre usuários dessa linguagem. Em outras palavras, deve-se prestar atenção à cultura predominante entre usuários de uma linguagem. Você talvez já tenha visto em diversas ocasiões o argumento de que determinada linguagem é mais adequada porque muita gente usa, e portanto terá mais facilidade para obter ajuda, ou para encontrar bibliotecas que implementam alguma funcionalidade que você deseja. Na prática isso não funciona exatamente assim.

Comecemos com uma pergunta para refletir. Onde você espera obter melhor ajuda: em uma multidão de 1000 amadores ou em um pequeno grupo de 10 especialistas? Eu sei que é difícil resolver essa equação sem levar em conta o fator intenção (já que um amador motivado e bem intencionado tende a ajudar mais que um especialista indisposto a ajudar), mas consideremos que ambos os grupos tenham igualmente a intenção de acolher os novatos. Neste sentido, perceba que a qualificação da ajuda é tão ou mais importante que a quantidade de ajuda disponível.

A popularidade diz respeito apenas à quantidade de pessoas que resolveram aprender uma linguagem, e isso pode ocorrer por diferentes motivos, muitos deles egoístas mesmo. Comunidade, porém, diz respeito a fazer parte de um grupo onde todos se ajudam pelo mero prazer de ajudar e fortalecer o grupo como um todo. Um programador capaz não se intimida com a impopularidade de uma linguagem, se ainda assim souber que há uma comunidade ativamente trabalhando nela.

Para além do fator suporte, a disponibilidade de bibliotecas também precisa ser considerada com bastante cautela. A mera disponibilidade de uma biblioteca pouco diz sobre a sua qualidade. Sem um processo adequado de auditoria por pares e revisão do código, uma biblioteca pode ser incorreta, ineficiente ou mesmo fraudulenta. Não por acaso, bibliotecas de terceiros são um frequente vetor de ataques na programação. Em outras palavras, o programador deve sim conhecer o código que está incluindo em seu projeto.

Ainda outro indicador interessante a se observar é como as linguagens envelhecem. Algumas envelhecem bem, se estabilizando no seu desenvolvimento, mas com correções e evoluções pontuais. Seguem mudando quando necessário, mas sem comprometer aplicações desenvolvidas para versões mais antigas. Geralmente são usadas em aplicações que igualmente envelhecem bem. Outras envelhecem mal, quebrando reiteradamente a compatibilidade com versões anteriores, e frequentemente usadas em aplicações marcadas por problemas não corrigidos ou apenas remendados dada a excessiva complexidade infiltrada.

Veja, portanto, que o histórico de uma linguagem pode endossá-la ou condená-la. Não se trata de uma regra absoluta, mas prestar atenção a este fator também é importante.

Mas como explico isso para meu chefe?

Legal, vamos colocar os pés no chão agora e lembrar de uma dura realidade: nem sempre podemos escolher. Ao programar profissionalmente você vai se deparar com situações em que é impossível ou muito difícil usar as ferramentas que gostaria. Isso pode ocorrer por vários motivos. Em alguns, talvez haja algum espaço para mudança. Em outros, será necessário superar esse desgosto e trabalhar em um cenário não ideal. Para tornar essas situações menos amargas, vamos discutir algumas entrelinhas.

Primeiro de tudo, saiba separar as coisas. Uma coisa é o ambiente de desenvolvimento que você precisa usar profissionalmente. Outra é o que você escolhe para projetos pessoais e para o seu aprendizado. Como eu disse anteriormente, existem linguagens que são interessantes para fortalecer o aprendizado da programação, e esse conhecimento nunca é perdido. Ele abrirá novas perspectivas para o pensamento e pode até mesmo lhe fornecer ideias valiosas para trabalhar em um ambiente que você não gosta.

Segundo ponto: mesmo as linguagens mais deploráveis (e não entrarei no mérito de quais são) são capazes de ensinar algo. Mesmo essas possuem um ou outro ponto positivo. Em condições nas quais não possa evitá-las, tente extrair o máximo disso. Ao mesmo tempo, não é possível criticar com propriedade aquilo que você não conhece com profundidade. Mesmo que não lhe agrade, veja como uma oportunidade de justificar a sua crítica de modo mais embasado. Quem sabe não seja exatamente isso que você precisa para provar para o seu chefe que essa é uma opção inadequada, mostrando o porquê e então apresentando uma alternativa melhor? Ou talvez, ao conhecer mais, você mude sua opinião e pense que não é tão ruim assim.

Terceiro, ao decidir sobre novas implementações, você pode achar difícil argumentar com seu chefe (entenda-se quem vai decidir, individualmente ou coletivamente) sobre uma opção que considera mais adequada. Isto talvez seja assim porque muita gente faz isso, e a responsabilidade do chefe, entre outras coisas, é garantir que as preferências pessoais dos desenvolvedores não se sobreponham ao objetivo do projeto. Ainda assim, se estiver verdadeiramente comprometido com esse objetivo, não recusará uma escolha que possa ser comprovadamente eficaz. Se em vez de argumentos você apresentar provas de que a solução apontada é mais adequada, suas chances de convencimento aumentarão. Se possível, proponha fazer uma prova de conceito para validar a sua sugestão.

Sei que lidar com chefes/clientes pode às vezes ser difícil e eu definitivamente não quero aqui instigar nenhum tipo de atitude que possa te prejudicar profissionalmente. Mas lembre-se de avaliar periodicamente as opções disponíveis. Às vezes não será possível fazer melhores escolhas técnicas no ambiente de trabalho atual, mas será possível fazer isto em outro.

O que devo escolher, afinal?

Se você pulou para este tópico deliberadamente, na esperança de que aqui teria uma resposta resumida, eu sinto lhe decepcionar. Você não espera, em sã consciência que eu tenha discorrido tantas ideias até aqui, para ao final fazer a escolha por você. Se este é o caso, sugiro que tome o devido tempo para ler o artigo inteiro. Eu sei que essa resposta pode parecer insatisfatória nesse instante, mas acredite, se você não fizer uma escolha informada, acabará por gastar seu tempo e esforço de forma aleatória.

Referências

Por fim, enumero aqui alguns artigos que foram inspiração para esse texto, e os quais também recomendo.

prog/qual-ambiente-escolher.txt · Última modificação: 2023/01/18 22:12 por hrcerq