Parte IV · Overview — do design da linguagem a um programa em execução

draft

Uma linguagem de programação é duas coisas ao mesmo tempo: um design (o que você consegue expressar e o que o compilador garante) e uma implementação (a maquinaria que transforma fonte em comportamento). Gerência de memória vive na costura entre as duas — é uma escolha semântica com consequências de runtime.


O pipeline

fonte ──▶ lexer ──▶ parser ──▶ AST ──▶ análise semântica / tipos ──▶ IR ──▶ codegen ──▶ código de máquina
                                                                                   │
                                                                                   ▼
                                                                        runtime (execução + MEMÓRIA)

O front-end (lexerparserAST — o kparse da Koda) estabelece *o que o programa significa. O *back-end o rebaixa a código de máquina. O runtime carrega o que não pôde ser resolvido estaticamente — dispatch dinâmico, exceções, concorrência, e reclamação de memória*

Onde a gerência de memória se encaixa

Duas perguntas decidem todo o caráter de performance e segurança de uma linguagem:

  1. Quem libera a memória? — o programador (manual), o compilador (estático: ownership,

    regiões), ou o runtime (dinâmico: garbage collection, reference counting)?

  2. Quando? — deterministicamente (num ponto conhecido do programa) ou eventualmente

    (quando o coletor rodar)?

Isso não são notas de rodapé de implementação; moldam a própria linguagem (o borrow checker do Rust existe pra responder isso em tempo de compilação; o sistema de efeitos do Koka habilita o reuse do Perceus). Pra uma linguagem que precisa ser rápida (competir com linguagens de sistema sem GC) e ergonômica, esta é a decisão central de runtime — por isso o próximo capítulo, Gerência de Memória, é o seed deste compêndio.