Tipos: o que é conferido, e quando
Anotar é opcional, e o que muda quando você anota. União, refinamento, opaco, genéricos — e onde o analisador cala de propósito.
A dúvida mais comum sobre tipos aqui não é como escrever — é quem confere, e quando. Há duas metades, e elas respondem em momentos diferentes: o dataforge check responde antes de rodar, o interpretador responde na fronteira. Saber qual está falando economiza muito tempo.
Anotar é opcional; conferir não é#
dataforge
// sem anotacao: roda, e o check cala sobre o tipo
x := 10
// com anotacao: o check prova o que der para provar, e a execucao
// confere na fronteira
idade: Integer := 30
action dobro(n: Integer) -> Integer:
yield n * 2
assert dobro(idade) is 60
out "o tipo declarado vale na entrada e na saida"`type`: uma declaração, seis formas#
O que muda é o que vem depois do :=.
dataforge
type Id := Integer // alias
type Numero := Integer | Float // uniao
type Positivo := Integer where valor bigger 0 // refinamento
action guardar(p: Positivo) -> Integer:
yield p
assert guardar(7) is 7
out "o refinamento vale em TODA fronteira, nao so na criacao"`<T>` solto não é conferido; `<T extends X>` é#
dataforge
// sem limite: documenta a relacao, e aceita qualquer valor
action eco<T>(x: T) -> T:
yield x
// com limite: cobrado nas duas metades — o check na chamada, a
// execucao no valor. E dentro do corpo, um 'T extends Number' E um
// Number para o analisador: e o que deixa escrever 'a bigger b'.
action maior<T extends Number>(a: T, b: T) -> T:
yield a given a bigger b otherwise b
assert eco("oi") is "oi"
assert maior(3, 9) is 9
out "o limite atravessa o adopt tambem"O que o `check` prova a partir de um literal#
| Acusa | Código |
|---|---|
xs[10] num cluster de três | indice-fora-do-alcance |
v["cidad"] num vault sem a chave, com sugestão | chave-ausente |
cycle i from 5 to 1 — nunca roda; step 0 — nunca termina | cycle-vazio |
1 is "1" — sempre no | igualdade-impossivel |
p.clientte num record, com sugestão | membro inexistente |
P.criar(1, 2, 3) vindo de outro arquivo | aridade entre módulos |
E o que ele cala, de propósito#
O silêncio é tão projetado quanto o alarme. Um falso alarme ensina a ignorar mensagens — e depois a desligar a verificação inteira.
- `v["k"] ?? padrao` não é acusado. O
??é exatamente o que a dica daquele erro recomenda: um analisador que acusa o conserto que ele próprio sugere é um analisador que se desliga. - Um parâmetro de tipo não é um tipo. Sem isso, a trilha ganhava dois alarmes no capítulo que ensina genéricos.
- O tipo declarado de uma ação decorada não vale. Não há como saber qual decorador substitui, e diante de duas respostas ele cala.
- `xs[-1]` continua livre — tratar todo negativo como fora do alcance acusaria a forma normal de pegar o último item.
Silenciar uma regra, de propósito#
dataforge
cores := ["azul", "verde"]
// A regra tem de ser NOMEADA: um 'permitir' solto esconderia o erro
// seguinte, que ninguem pediu para esconder.
match cores:
point c: // df: permitir point-inalcancavel
out $"casou com {len(c)} cores"
out "a regra vale na linha, ou na de cima"