Pular para o conteúdo

Racional · ensaio 01

Filosofia

rationale.md · 89 linhas · 4 min de leitura

Os modelos mentais-raiz de onde tudo deriva. Foram fixados antes da sintaxe, porque sintaxe coerente não se desenha keyword por keyword.

A maioria das linguagens cresce por acreção: decide-se match hoje, ponteiros semana que vem, declaração depois. São três decisões locais que não conversam, e o resultado é uma colcha de retalhos onde cada conceito novo nunca encaixa bem. Makoto inverteu a ordem: definir primeiro os princípios transversais, e deixar cada construto cair quase sozinho a partir deles.

Há uma hierarquia de princípios, do mais aplicado ao mais geral:

  1. Teste do opt-in (a métrica): você só paga pelo que convoca. Um conceito é caro se quem não o usa precisa entendê-lo. Daí decorre o corolário: o default é sempre o não-marcado. Privado é pelado, pub é a marca; imutável é o := pelado, var é a marca; seguro é o normal, unsafe é a marca. Isso não é um princípio à parte; é o opt-in aplicado a cada eixo.
  2. Não-envenenamento (a aplicação local): cada subsistema carrega só as suas cores. As interfaces de memória não dizem qual memória; o IO não diz sync/async; o namespace global não carrega função nenhuma. Um subsistema não pode “envenenar” os outros vazando seus detalhes.
  3. Sistemas-e-fronteiras / tainted coloring (a lei geral): a que governa as duas acima. Toda cor pertence a um reino; o pecado é a cor de um reino manchar outro. “Envenenamento” é só o nome dessa mancha vista de dentro.

E duas regras de forma que caem desses princípios:

  • Unificação por conceito. Quando N keywords exercem o mesmo verbo em objetos diferentes, viram uma. switch/match/select match (o objeto desambigua); for/while/loop-infinito loop. Mas, e este é o ponto fino, “mesmo verbo” quer dizer mesma operação e mesmo reino, não mesma forma. struct, enum e interface têm corpos de formato diferente e mesmo assim unificam sob decl, porque são o mesmo ato (declarar um tipo) no mesmo reino (o sistema de tipos). union tem corpo idêntico ao da struct e mesmo assim não unifica, porque é outra operação (reinterpretar bytes) em outro reino (o unsafe). Unificar pela semelhança de superfície seria cometer o próprio pecado da #3.
  • Eixos se preservam, não se fundem. let/var/const parecem “três formas de declarar”, mas são um eixo de mutabilidade com um default. Fundir num bind(mode=mut) apagaria o eixo: os nomes distintos são a informação visual, não ruído. A regra: se é um ato com objetos diferentes, unifique; se é um ato com um eixo-de-modos, preserve o eixo.

E a arquitetura que tudo isso projeta para o ecossistema: os tiers (cap. 11), com estabilidade em camadas, o core add-only embaixo e o que muda mais rápido vivendo mais acima.

Os princípios não são estética; são uma máquina de decisão. Quando uma proposta chega (“e se a gente desse uma keyword separada para cada forma de importar?”), ela é testada contra os princípios em vez do gosto. A resposta foi unificar tudo sob use (importar é um ato só): a forma depois da keyword é que carrega a intenção. use json qualifica (json.parse), use json.{parse} levanta o nome (parse), use json as j apelida. Uma keyword, três intenções na sintaxe, sem três palavras. E quando o princípio prevê uma escolha que você já tinha feito por instinto (privado-pelado, UTC-no-core e IANA-opt-in), é sinal de que o princípio é real, não imposto.

  • Por que não desenhar keyword por keyword? Porque gera inconsistência: decisões locais que não conversam. Os princípios primeiro é o que dá poucas keywords e coerência ao mesmo tempo.
  • Por que não unificar tudo que parece igual (struct/interface sob um type)? Porque apagaria a fronteira entre dados e despacho, exatamente o que a lei #3 proíbe. A forma engana; o que conta é operação + reino.
  • Por que não convenção (capitalização = público, à la Go)? Porque escopo não deve depender de convenção atenção-dependente; deve ser marca explícita. É o opt-in aplicado à visibilidade.

Sem princípios explícitos, a contagem crua de decoradores assusta; “tantos decoradores soltos?” parece caos. Reorganizados, eles são o índice de 4 a 5 subsistemas (@mm é memória; @supervisor/@transfer são concorrência; @cimport/@asm são FFI). A contagem crua é ruído; agrupada por sistema, é organização. O princípio é o que transforma “lista arbitrária” em “mapa”.

O default é o não-marcado; você marca quando sai do caso comum. E unifica-se por operação + reino, nunca por forma.

A disciplina custa consolidação. Você não pode simplificar struct/interface numa keyword só, mesmo parecendo tentador, porque viola a fronteira. O sigil @ acaba indexando de 6 a 7 subsistemas (mais denso visualmente do que um punhado de keywords seria), e os eixos exigem nomes distintos (let, var, const) em vez de um construto parametrizado. Em todos os casos a escolha foi clareza conceitual sobre economia de superfície: mais símbolos, mas cada um é sinal.

Próximo: 02 · Memória