Por que existem tantas linguagens de programação?
Atualmente, há diversas linguagens de programação que são utilizadas dentro de empresas, muitas vezes para finalidades parecidas.
No começo podemos achar isso estranho, porque se o objetivo é o mesmo, não seria possível usar uma mesma linguagem para todos esses projetos?
Para responder essa pergunta, primeiro é necessário lembrar que cada um desses projetos mesmo que tenham características parecidas, como ume usuárie que insere informações em uma página web, e essa página envia essas informações à um servidor. Alguns fatores podem mudar a escolha da tecnologia desse projeto, como:
- Esse projeto será desenvolvido por uma pessoa, um grupo pequeno ou dezenas de pessoas?
- Quais recursos esse sistema utilizará? Só leitura e escrita de dados, ou terá comunicação em tempo real? Inteligência artificial? Análise de dados? etc.
- Como será a arquitetura do sistema? Monolito ou microserviços?
- Será um projeto feito para uma empresa ou pessoa cliente, ou será um projeto criado dentro de uma empresa, para uso próprio?
Todas essas perguntas, e mais outras, vão determinar a tecnologia que um projeto terá. É por isso que por exemplo, existe tanta startup usando NodeJS, Elixir, Golang, etc; enquanto projetos de clientes menores, como lojas ou pequenas empresas, são feitos com PHP ou C#. A tecnologia do projeto está estritamente ligada a como ele é.
Golang e Rust
Golang, mais conhecida como Go, e Rust são duas linguagens muito populares hoje em dia, sendo usadas principalmente para back-end (lado do servidor), e em utilitários de linha de comando, que são programas que rodam em terminais, e geralmente servem para alguma necessidade momentânea, não precisam ficar rodando a todo momento.
Inclusive, um ótimo exemplo de programa que roda por linha de comando é o [Transchange](http://github.com/lissatransborda/transchange). É um projeto criado para facilitar o processo de transição de gênero social de pessoas trans, alterando o nome da pessoa em todos os repositórios dela, o que proporciona mudar até a autoria dos commits.
Golang
Golang é uma linguagem de programação criada pela Google em 2009. seu objetivo é ser leve, rápida, e produtiva.
Go foi criada com fortes inspirações de uma outra linguagem, o C, que foi e é uma das linguagens mais importantes da história.
Mesmo que Golang tenha várias funcionalidades, e possa ser usada para diversos fins, ela possui um foco muito grande em concorrência. Concorrência, de forma básica (porque esse conceito merece um artigo inteiro só sobre ele) é a capacidade de gerenciar mais de uma tarefa ao mesmo tempo, fazendo uma tarefa em um momento, parando, fazendo outra tarefa no lugar, e voltar naquela mesma tarefa anterior.
Um exemplo de concorrência sou eu fazendo esse artigo. Eu escrevo ele, levanto, dou uma andada, tomo água, escrevo mais um pouco, abro o Twitter e me perco nele por uns 15 minutos, volto a escrever, etc.
Inclusive, não confunda a concorrência com paralelismo, que é fazer algo ao mesmo tempo. Paralelismo seria eu nesse momento, escrevendo esse artigo ouvindo música.
Rust
Rust é uma linguagem criada pela Mozilla em 2012, focada em programação baixo nível, velocidade, e praticidade, tendo as descrições dos erros que ocorrem nas tentativas de compilar o código detalhadas, e mostrando visualmente onde ocorreu o erro, colocando até mesmo um trecho do código que deu erro na tela.
Um dos principais focos da linguagem é a segurança contra erros. Um exemplo dessa alta segurança é que, por padrão, toda variável dentro do Rust é imutável. Isso significa que seu valor não pode ser alterado, sendo atribuído uma única vez. Para criar variáveis que possam ter seu valor alterado, isso deve estar explícito na criação da mesma.
Rust também é uma tecnologia ótima para criação de programas desktop e utilitários de linha de comando, pois ela tem suporte à bibliotecas e funções do C, então tudo que pode ser feito com C, também pode ser feito com Rust.
Inclusive, atualmente estão sendo desenvolvidos uma versão do núcleo Linux em Rust (no momento feito em C) e também uma versão do Windows feita também em Rust.
Agora que já sabemos um pouco sobre cada linguagem, vamos fazer um comparativo de cada uma em pontos que julgo importante para uma linguagem de programação.
Instalação
Golang
Há uma página na documentação do Golang focada em sua instalação. Esta inclui uma série de passos, que envolvem editar variáveis do sistema, baixar o Go manualmente e colocar em pastas do sistema, etc.
Mesmo que este tutorial seja simples, e possa ser feito copiando e colando, de primeira, pode parecer algo perigoso ou estranho para uma pessoa iniciante em tecnologia, que não tem esse costume de copiar e colar comandos de terminal, e muitas vezes nem sabe o que esses comandos significam.
Então mesmo que essa instalação pareça trivial, e tenha pouca possibilidade para erros, ela pode soar perigosa para quem está iniciando.
Rust
Diferentemente do Golang, Rust possui um script de instalação. Isso significa que podemos copiar um único comando, que diversos outros serão executados de forma automática, instalando o programa "como se fosse mágica".
Acho melhor esse método por ser mais prático, e simples para a pessoa desenvolvedora final, pois não será necessário copiar diversos comandos, ela precisa de um só.
Essa forma também reduz o problema da pessoa iniciante copiar comandos que ela não entende, pois dessa forma soa até um pouco "mágica", sabe? Algo mais simples, para a pessoa não sentir tanto receio.
Hello World
"Hello World" é o desafio mais simples de qualquer linguagem de programação. Ele é importante para sabermos na prática a quantidade de código base que precisamos escrever para rodar um código, e também como a linguagem é estruturada.
Golang
No Golang, o Hello World pode ser feito dessa forma:
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
Analisando esse código de forma mais detalhada:
A primeira linha cria um pacote. Em Go, pacotes são coleções de código, e todo projeto tem que ter obrigatoriamente pelo menos um pacote. No nosso caso, o pacote será main.
Depois disso, na linha dois, importamos uma biblioteca chamada fmt
, que é a sigla para Format (formatação). Essa biblioteca tem diversas funções relacionadas à mostrar dados na tela, tanto textos simples como Hello World, ou textos que exigem mais formatação, como colocar variáveis dentro desse bloco.
Na linha três, é declarada a função principal de qualquer projeto Golang, a main
. É nessa função que o nosso programa vai começar a rodar, então podemos ter quantas outras funções quisermos, porém a main sempre será a única necessária, e também a principal.
Na quatro, executamos a função que mostra o Hello World na tela, a println
. Como essa função está dentro do pacote fmt
, teremos que chamar esse pacote, colocar um . para indicar que teremos algo dentro dele, e a primeira letra terá de ser maiúscula por conta dessa função (poderia também ser uma variável, tipo, classe, etc.) estar dentro de um pacote externo. Depois disso, é só inserir o texto dentro da função entre aspas duplas.
Diferente de outras linguagens, Golang não aceita aspas simples nesse caso, elas só funcionariam se o nosso texto tivesse um único caractere.
Na linha 6, apenas fechamos a função main, finalizando nosso código.
Rust
Já no Rust, podemos criar um Hello World dessa forma:
fn main() {
println!("Hello, world");
}
Na primeira linha, assim como o Golang, temos que criar uma função main, que também será a principal do nosso código.
Na segunda linha, usamos a função println!
. A exclamação no fim é por conta dessa função ser uma macro, um conceito que não vou abordar nesse artigo por ser algo mais avançado do Rust. Semelhante ao Go também é necessário usar aspas duplas, porque as aspas simples são exclusivas à representação de um único caractere.
E por fim, na terceira linha, fechamos o método main
, finalizando nosso código.
Como pudemos ver, em ambas as linguagens o Hello World não é complexo, e explicando linha por linha conseguimos entender o motivo de comando de ambos os códigos. Mas, o Hello World do Rust acaba sendo mais fácil de entender, por não precisar criar um pacote, e nem importar uma biblioteca para mostrar dados na tela.
É importante lembrar que cada linguagem tem as suas características, então um Hello World ser simples, ou mais complexo, é uma escolha de arquitetura. Às vezes, uma linguagem que já possui um monte código padrão, facilita para continuarmos desenvolvendo nosso projeto, enquanto outras que são mais simples, podemos encontrar mais dificuldades na frente. Então, não leve o Hello World como algo essencial para saber se uma linguagem é "melhor" que a outra.
Rodando o código que criamos
Agora precisamos rodar esses códigos, e pra isso é necessário descobrir como essas linguagens processam o nosso código para executar na nossa máquina.
Golang
Golang é uma linguagem compilada, isso significa que o código será transformado diretamente em código de máquina. Essa forma é muito interessante para linguagens de programação que se propõem a serem rápidas, pois o código de máquina executa direto no sistema, sem precisar de alguma máquina virtual ou processo no meio.
Mas nessa forma também há uma desvantagem: Esse código de máquina é de uma única plataforma, que de forma básica, é o local onde você está rodando esse código, então Windows, Linux, um celular Android, iOS,etc. Então seria necessário compilar para cada plataforma, gerando um executável separado. Mas tirando isso, é só felicidade.
Para compilar o código, podemos usar o comando:
go build helloworld.go
Com isso, nosso programa será compilado, e teremos um executável chamado helloworld, que em Linux poderemos executar com ./helloworld
, e em Windows com helloworld.exe
.
Também podemos executar um programa sem precisar compilar, e depois rodar. Para fazer os dois de uma vez, podemos usar o comando abaixo:
go run helloworld.go
Enquanto o build apenas compila, o run compila e executa.
Rust
A compilação funciona da mesma forma que no Golang, criando um executável com o nosso código, então nesse quesito os dois são iguais.
Para compilar esse código que criamos em Rust, temos que usar o comando abaixo:
rustc helloworld.rs
E depois, para executar, podemos executar da mesma forma que no Golang, no Linux com ./helloworld, e em Windows com helloworld.exe.
Como vimos, as duas linguagens compilam o código diretamente em código de máquina, a diferença é que o Golang tem um comando direto para compilar e executar o código, enquanto no Rust precisamos compilar, e depois executar. De resto as duas são muito parecidas.
Lidando com erros
Agora vamos falar sobre como essas linguagens mostram os erros no código, e se essa forma de informar os erros é compreensível ou não.
Golang
Para testar o sistema de erros do Golang, fiz algumas mudanças no código, sempre inserindo algum erro que realmente poderia acontecer enquanto você escrevia o código, sendo em sequência:
Errando o nome da função println
package main
import "fmt"
func main() {
fmt.Printl("Hello World")
}
Erro: undefined: fmt.Printl
Não colocando fmt antes da println
package main
func main() {
Println("Hello World")
}
Erro: undefined: Println
Não colocando func antes da main()
package main
import "fmt"
main() {
fmt.Println("Hello")
}
Erro: syntax error: non-declaration statement outside function body
Como podemos ver, as mensagens de erro são bem simples, geralmente uma única frase descrevendo o erro. Pessoalmente acho que a utilidade dessas mensagens variam muito da sua experiência, uma pessoa iniciante pode se confundir muito pra entender o que fez de errado, enquanto pessoas com mais experiência vão saber o que fizeram de errado de uma forma bem mais rápida.
Rust
Para testar os erros do Rust fiz o mesmo processo, gerando 3 erros, sendo:
Não colocando ! depois de println
fn main() {
println("Hello, world!");
}
Erro:
error[E0423]: expected function, found macro `println`
--> src/main.rs:2:5
|
2 | println("Hello, world!");
| ^^^^^^^ not a function
|
help: use `!` to invoke the macro
|
2 | println!("Hello, world!");
| +
Usando aspas simples ao invés de aspas duplas
fn main() {
println!('Hello, world!');
}
Erro:
error[E0762]: unterminated character literal
--> src/main.rs:2:28
|
2 | println!('Hello, world!');
| ^^^
Errado a escrita da função println!
fn main() {
printl!("Hello, world!");
}
Erro:
error: cannot find macro `printl` in this scope
--> src/main.rs:2:5
|
2 | printl!("Hello, world!");
| ^^^^^^ help: a macro with a similar name exists: `print`
Considero os erros do Rust bem mais descritivos que os do Golang, por mostrar as linhas do código e apontar qual lugar exato que tem o erro, facilitando na compreensão e resolução.
Documentação e conteúdos
Quando começamos a aprender uma linguagem, é muito importante pensarmos onde iremos aprender mais sobre ela, então vamos ver um pouco sobre documentação e conteúdo das duas linguagens.
Golang
Go tem uma documentação oficial, indo desde a instalação, até questões bem avançadas da linguagem. Isso é bom, mas infelizmente não há uma tradução para português dessa documentação, algo que eu acho bem chato.
Mas tem um canal que eu gosto muito chamado Aprenda Go, onde a Ellen Korbes tem um curso maravilhoso, e totalmente em português. Recomendo demais!
Rust
Rust tem uma documentação oficial da mesma forma que o Golang, mas é completamente em inglês. Também há uma documentação criada pela comunidade feita em português, que também pode ser uma ótima opção.
Em português não conheço um curso completo gratuito, mas o Bruno Rocha produz bastante conteúdo sobre a linguagem em suas redes, como no seu canal do Youtube. Caso queria começar, acho bem legal.
Conclusão
Para mim, ambas as linguagens são ótimas, mas cada uma tem um estilo diferente, e atende públicos e requisitos específicos.
Por exemplo, para aplicações web todo o ecossistema Golang está bem mais desenvolvido, então pode ser interessante, mas para aplicações de desktop ou de terminal, que precisam da maior velocidade e segurança possível, Rust pode ser uma linguagem mais adequada.
Muito obrigada por ler ❤️🏳️⚧️ e me segue nas redes, é tudo @lissatransborda 👀