Nosso amigo compilador
Tags: rust, beginners
Published: 2023-06-06 15:19:11

Dando sequência aos posts sobre Rust aqui no dev.to, vamos falar sobre compilação, afinal Rust é uma linguagem de programação compilada. Mas o que isso quer dizer?

As linguagens de programação podem ser classificadas em três categorias principais: **compiladas**, **interpretadas** e aquelas que usam **bytecode**. Cada uma dessas abordagens possui características distintas que afetam o processo de execução do código. Vamos explorar essas diferenças:

**Linguagens compiladas** são aquelas em que o código-fonte é traduzido integralmente para um código de máquina específico antes da execução. O compilador é responsável por converter todo o código-fonte em um arquivo executável, que pode ser diretamente executado pelo sistema operacional. Exemplos de linguagens compiladas incluem C, C++, Java (em alguns casos) e Rust.

A principal vantagem das linguagens compiladas é que a tradução antecipada para código de máquina resulta em uma execução geralmente mais eficiente e rápida. Além disso, erros de sintaxe e semântica são identificados durante a etapa de compilação, o que ajuda a encontrar problemas antes da execução do programa. No entanto, a compilação pode exigir mais tempo e recursos, especialmente para programas maiores.

**Linguagens interpretadas** são aquelas em que o código-fonte é executado linha por linha, em tempo real, por um programa chamado "interpretador". O interpretador analisa cada instrução do código-fonte e executa as ações correspondentes. Exemplos de linguagens interpretadas incluem Python, JavaScript, Ruby e PHP.

Uma das principais vantagens das linguagens interpretadas é a sua portabilidade, pois o código-fonte é independente da arquitetura do sistema. Além disso, as linguagens interpretadas são frequentemente mais flexíveis, permitindo a execução interativa e a modificação dinâmica do código em tempo de execução. No entanto, o processo de interpretação pode ser mais lento em comparação com a execução de código compilado, uma vez que as instruções são analisadas em tempo real.

Algumas linguagens utilizam uma abordagem intermediária, chamada de **bytecode**. Nesse modelo, o código-fonte é compilado para um formato intermediário, chamado bytecode, que é executado por uma máquina virtual específica. A máquina virtual é um programa que interpreta e executa o bytecode. Exemplos de linguagens que usam bytecode incluem Java, C#, Python (em algumas implementações) e Ruby (em algumas implementações).

O bytecode é um código de máquina simplificado e independente de plataforma, projetado para ser executado de forma eficiente pela máquina virtual. Essa abordagem combina algumas vantagens das linguagens compiladas e interpretadas. Por um lado, o bytecode é pré-compilado e pode ser executado mais rapidamente do que a interpretação direta do código-fonte. Por outro lado, a máquina virtual oferece portabilidade, pois pode ser executada em diferentes sistemas operacionais e arquiteturas.

As linguagens compiladas apresentam algumas vantagens em relação às linguagens interpretadas ou de bytecode, especialmente no que diz respeito à velocidade. Como o código-fonte é traduzido diretamente para código de máquina, as linguagens compiladas tendem a ter um desempenho melhor em termos de velocidade de execução. Isso ocorre porque o código compilado é otimizado para a arquitetura do sistema e pode aproveitar ao máximo os recursos disponíveis. Em contraste, as linguagens interpretadas precisam analisar e executar as instruções em tempo real, o que pode resultar em uma execução mais lenta.

Outro ponto muito importante é que o compilador é seu melhor amigo pois têm a capacidade de otimizar o código durante a compilação, o que pode resultar em um uso mais eficiente dos recursos do sistema. Ele também podem aplicar técnicas como inlining de funções, eliminação de código morto e otimizações de laços para melhorar o desempenho. Por outro lado, os interpretadores não têm a mesma capacidade de otimização, pois executam o código linha por linha sem uma visão completa do programa.

Além disso os compiladores verificam o código-fonte em busca de erros de sintaxe e semântica durante a etapa de compilação. Isso significa que muitos erros são identificados antes mesmo da execução do programa, o que ajuda os desenvolvedores a corrigirem problemas de forma mais eficiente. Nas linguagens interpretadas, os erros são geralmente detectados durante a execução, o que pode levar a um ciclo de desenvolvimento mais lento ou problemas em produção.

Outra vantagem é que nas linguagens compiladas, o código é transformado em um executável que pode ser implantado e executado em qualquer sistema operacional compatível. Isso facilita a distribuição do software, pois os usuários não precisam ter o compilador ou interpretador instalado em suas máquinas. Em contraste, nas linguagens interpretadas ou de bytecode, os usuários precisam ter o interpretador correspondente instalado para executar o código (por exemplo um interpretador JavaScript ou o .NET ou o JRE).

É importante ressaltar que cada abordagem tem suas próprias vantagens e desvantagens, e a escolha entre linguagens compiladas, interpretadas ou de bytecode depende das necessidades específicas do projeto e dos compromissos que os desenvolvedores estão dispostos a fazer em termos de velocidade, facilidade de desenvolvimento e outros fatores.

## O compilador do rust, nosso melhor amigo

Um dos grades trunfos do Rust é o seu compilador, que além das vantagens apresentadas, realiza diversas transformações e verificações antes efetivamente rodar seu código. Mais do que isso, ele lhe dá mensagens claras e efetivas do que está errado, por que está errado e onde corrigir. 

![A imagem apresenta um erro reportado pelo compilador do rust ao tentar atribuir uma sequência de caracteres a uma variável do tipo inteiro](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzyzsky5ws6o4h08ll4f.png)

Além dessa mensagem clara e direta do que está errado e por que, ele ainda permite usar a diretiva `explain` para detalhar melhor o erro. No caso da imagem, nosso erro é o E0303. Dessa forma basta rodar o comando a seguir:

```
$ rustc --explain E0308
```

E um retorno detalhado do problema será apresentado:

```
Expected type did not match the received type.

Erroneous code examples:


fn plus_one(x: i32) -> i32 {
    x + 1
}

plus_one("Not a number");
//       ^^^^^^^^^^^^^^ expected `i32`, found `&str`

if "Not a bool" {
// ^^^^^^^^^^^^ expected `bool`, found `&str`
}

let x: f32 = "Not a float";
//     ---   ^^^^^^^^^^^^^ expected `f32`, found `&str`
//     |
//     expected due to this


This error occurs when an expression was used in a place where the compiler
expected an expression of a different type. It can occur in several cases, the
most common being when calling a function and passing an argument which has a
different type than the matching type in the function declaration.
```

Ou seja, além de não deixar o código problemático ir para produção validando antes de o executar, ele ainda pode ser uma fonte incrível de aprendizado. 

## Como aprender Rust?

Nessa série de artigos que estou publicando aqui no dev.to vou apresentar a linguagem Rust do zero, desde a instalação do ferramental necessário e configuração do editor de textos até a criação de uma API simples usando bibliotecas de mercado.
 
Se você se interessa por Rust seja por novas oportunidades profissionais, seja apenas pra aprender algo novo, me siga aqui ou [no meu Twitter](https://twitter.com/mfcastellani). Planejo publicar um artigo a cada dois dias, se tudo der certo. 

Você também pode dar uma olhada no material oficial da linguagem, [com acesso gratuito aqui](https://doc.rust-lang.org/stable/book/). Ou [no meu livro](https://www.casadocodigo.com.br/products/livro-rust), escrito junto com meu amigo de longa data [Willian Molinari](https://pothix.com/), que está em sua segunda edição.

Também tem o sensacional livro [Programming Rust](https://www.amazon.com.br/Programming-Rust-Fast-Systems-Development/dp/1492052590/), que cobre a linguagem de ponta a ponta além de diversos outros pontos em suas mais de setecentas páginas. 

Aprender uma nova linguagem de programação pode ser desafiador e excitante. Espero que embarque nessa viagem comigo.