Módulos e ecossistema
Objetivo: organizar código no modelo bin/lib, importar com
use, entender os tiers de estabilidade, e conhecer as libs oficiais e o CLImk.
Módulo = lib; projeto = bin
Seção intitulada “Módulo = lib; projeto = bin”Dois marcadores, com papéis distintos:
mk.modmarca um módulo, e um módulo é uma lib: uma caixa independente e reutilizável, com suas próprias dependências. Funciona como fronteira de namespace e de dependência. Nunca é compilado sozinho, apenas como parte da árvore de um projeto (módulos não-usados convivem sem custo).mk.projectmarca o bin (o compositor): o módulo de topo e a unidade de compilação. Compõe os módulos numa árvore, declara a versão da linguagem, suas deps, e as tasks/produção de binário.
myapp/ ← mk.project (BIN: compõe módulos, tasks, deps)├── mk.project├── mk.sum (lockfile, auto-gerado)├── main.mko → módulo "myapp"├── auth/ ← mk.mod (LIB "myapp/auth", deps próprias)│ └── tokens.mko└── store/ ← mk.mod (LIB "myapp/store") └── db.mkoO manifesto declara a versão da linguagem e as deps (estilo go 1.21):
package myappmakoto 1.0
deps { github.com/acme/http 2.3.1}Importar: use
Seção intitulada “Importar: use”use json // monta o módulo → json.parse(...)use json.{parse, decode} // levanta nomes → parse(...) diretouse json as j // aliasDe onde vem cada use é decidido pelo prefixo: bare é stdlib (use io); nome-do-pacote é local
(use myapp/auth); forma URL é externo (use github.com/acme/http). Imports são absolutos a partir
do nome do pacote, nunca ../. Ciclos são proibidos.
Os tiers de estabilidade
Seção intitulada “Os tiers de estabilidade”O ecossistema é organizado por quão livremente se pode mexer no contrato:
- Tier 0, o core (a linguagem mais a stdlib): padrões que não mudam (IEEE, TCP/IP, UTF-8, lista
linkada). É add-only: acrescenta-se, nunca se edita o contrato.
collections(List/Map/Set) é tier 0, um conjunto fechado (nunca haverá uma “quarta coleção fundamental”). - Tier 1, as libs oficiais: especificações que evoluem (HTTP teve 3 versões; regex troca de
algoritmo). Tem cadência própria (semver/changelog), é opt-in e custa peso zero até o
use.containersé tier 1, um roster que cresce (cada algoritmo dentro é frozen, mas a coletânea muda). - Tier 2, os frameworks (
web, a UI): mais opinião, mais giro. - Tier 3, os terceiros: a promessa de compatibilidade é de outro.
A regra é que tiers só dependem pra baixo. O corte às vezes parte um conceito ao meio: UTF-8 é tier 0, as tabelas Unicode são tier 1; UTC/offset é tier 0, os nomes de fuso IANA são tier 1.
As três libs oficiais (tier 1)
Seção intitulada “As três libs oficiais (tier 1)”http: cliente e servidor, sobre a camada 2 donet(bytes + TLS). Tem superfície agnóstica de versão (/1.1, /2, /3 negociados por ALPN), processo-por-stream (umpanicnuma request crasha só ela) e cliente full (pool/redirect/cookies/gzip). O framework (router/middleware) é oweb(tier 2).
use httpclient := http.Client.new()resp := client.get("https://api.exemplo/users") catch |e| { return e }if resp.status.is_success() { process(resp.body.to_string() catch |e| { return e }) }regex: multi-engine por construção.regex.compileusa RE2 (linear, sem ReDoS, o default),regex.pcre.compileusa backtracking (features completas), eregex.hyperscanfaz multi-pattern mais streaming. Padrão literal compila em comptime.
const WORD := regex.compile("[a-z_][a-z0-9_]*").or_panic() // comptime: valida + embarcacontainers:Deque,PriorityQueue,SortedMap/SortedSet(B-tree),Trie(ART),RingBuffer. Segue a convençãonew()(ordem natural) /with_order(cmp)(custom):
use containerspq := containers.PriorityQueue[Task].with_order(by_priority) // Task sem ordem natural → with_orderO CLI mk
Seção intitulada “O CLI mk”mk run / mk build / mk test / mk fmt / mk get / mk doc / mk lint / mk bench, e mais
(capítulo 15). Binário único, alias de makoto.
Próximo: 13 · FFI e baixo nível