Algumas considerações sobre Rust de um iniciante na linguagem

Recentemente iniciei um novo pet project que consiste em criar um emulador de CHIP-8. Resolvi programar ele com Rust para aprender mais sobre a linguagem. Fiz uma thread no twitter onde eu falo um pouco sobre isso e um pouco sobre o CHIP-8 (o mecanismo dele de desenhar na tela é bem genial/horroroso, inclusive).

Acabei pegando pouco no projeto esses dias porque estou meio sem tempo. No pouco tempo que tive, fiquei mais estudando Rust do que efetivamente programando o emulador. De fato, o emulador em si não parece ser um software muito desafiador. O desafio está sendo aprender Rust.

Eu achava que Rust seria uma espécie de C, pois as linguagens parecem competir no mesmo nicho. Eu não poderia estar mais enganado. Sim, uma das prioridades para se fazer Rust é o desempenho, assim como C. Mas, ao contrário de C, ela também tem ênfase em segurança. E mesmo a abordagem da linguagem para garantir alto desempenho me parece diferente da abordagem de C.

Assim como C, as abstrações de Rust não geram muito overhead de código na hora de compilar.

(Essa, aliás, é a resposta para a pergunta: "por que ainda se usa C?". Quem programa em C o faz porque há um controle muito grande sobre o código compilado a partir do código escrito. Isso é importante para quem precisa lidar com desempenho (sistemas embarcados, SOs etc). C, como sabemos, é uma linguagem com muitas limitações (muitas mesmo) que outras linguagens já corrigiram, mas ela também é muito honesta quanto à isso).

Voltando a Rust, ela tem uma filosofia de "zero-cost abstractions", onde as abstrações criadas na linguagem devem custar o mínimo possível para funcionarem. Com isso, a linguagem consegue um desempenho equivalente a C. Porém, ao contrário de C, Rust optou por não abrir mão de abstrações mais modernas. (Não que os criadores de C tenham optado pelo caminho contrário na sua concepção, afinal, a maior parte dessas ideias de abstrações ainda não eram tão difundidas na época).

Por exemplo, Rust tem uma espécie de "orientação a objetos". Eu não sei se é tecnicamente correto dizer que Rust é uma linguagem orientada a objetos, mas ela pelo menos tem algum sistema de objetos. O que normalmente conhecemos como classes foram divididos em três estruturas em Rust. As duas primeiras são implementações e structs.

Structs de Rust funcionam como as structs de C (armazenamento de dados), e as implementações são justamente as implementações de código que manipulam essas structs. Não há herança (deve-se usar composição) nas structs.


Além disso, há uma terceira estrutura chamada trait. Trait é uma espécie de interface, parecida com a que encontramos em Java. Você define um trait com assinaturas dos métodos e depois implementa eles com o impl. 

Porém, o aspecto mais interessante da linguagem é o foco em segurança. Por exemplo, não há NULL na linguagem (quando usada de modo seguro). Quando o preenchimento de uma determinada variável é opcional, declara-se a variável utilizando um enum Option.

Não há, também, manipulação de ponteiros como em C, mas uma manipulação de referências. Ao passar uma referência, você "empresta" (borrow) aquela variável para a função ou variável que está manipulando (e consequentemente não pode usar enquanto ela está emprestada!). Além disso, a linguagem analisa o tempo de vida da variável e não permite que você empreste uma referencia com tempo de vida menor do que a referência irá precisar.

Na época em que eu programava C profissionalmente, geralmente optava sempre que possível por usar alocações estáticas ao invés de alocações dinâmicas para mitigar problemas com ponteiros e memory leaks. Também evitava retornar ponteiros nas funções, com intuito de mitigar a possibilidade de retornar um ponteiro para uma variável cujo escopo acabasse ao final da função. O software que eu trabalhava, cujo tamanho eu considero médio, tinha talvez apenas um local de alocação dinâmica em toda sua execução.

Não só isso, em minha experiência, a falta de abstrações de C sempre gerou bastante overhead no tempo de desenvolvimento. Acho que Rust ataca os problemas certos. Embora ainda me falte um pouco de conhecimento em Rust para emitir alguma opinião minimamente embasada a respeito das soluções que ela propõe, estou achando bem interessante os novos paradigmas que ela usa.

Ah, e se alguém quiser acompanhar a evolução do emulador, eu estou depositando o código neste repositório: https://github.com/fsjunior/chip8-emulator-in-rust