Slide 23 de 74

Tipos declarados

Um struct
type User {
	id:   Int
	name: Str
}

proc main(): void {
	u := User(1, "ada")
	echo u.name
	echo User(name: "grace", id: 2).id   // por nome, em qualquer ordem
}
Uma união com tag, e seus campos compartilhados
type Event {
	at: Int                  // fora de todas as variantes: toda uma o tem
	Opened { by: Str }
	Closed
}

proc main(): void {
	e := Event.Opened("ada", 5)   // o campo próprio da variante primeiro, depois `at`
	echo e.at                      // 5 — um campo compartilhado é lido direto
	// echo e.by                   // erro de compilação: `by` pertence a Opened

	for each ev in [e, Event.Closed(9)] {
		echo ev.at
	}
}
Um tipo que contém a si mesmo
type Expr {
	Num { value: Int }
	Add { left: Expr, right: Expr }
}

type Folder {
	name: Str
	children: Folder[dyn]    // através de um vetor
}

proc main(): void {
	sum := Expr.Add(Expr.Num(1), Expr.Num(2))
	echo sum
	echo Folder("root", [Folder("docs", [])]).name
}

Um type sem variantes é um struct; com variantes, uma união com tag. Um valor é construído chamando o tipo ou a variante — User(1, "ada"), Shape.Circle(5) — e uma variante que não carrega nada também é chamada: Shape.Point(), já que Shape.Point sozinho nomeia a variante e não um valor dela. Os campos podem ser passados por nome, em qualquer ordem. Não existe subtipagem nem interface: uma variante é uma forma de construir e casar uma união, não um tipo próprio.

Um campo declarado fora de todas as variantes é adicionado a todas elas, depois dos campos próprios de cada variante, e é o único tipo de campo que um valor de união tem: event.at o lê direto. Todo outro campo pertence à sua variante e é alcançado casando com is, nos próximos slides — mesmo um que toda variante declare com o mesmo nome. Um valor de união é construído inteiro, então nenhum campo dele é atribuído sozinho.

Um tipo pode conter a si mesmo através de uma variante, que é o que uma árvore precisa, ou de um vetor. Um struct que contém a si mesmo diretamente, ou através de um Result, nunca poderia ser terminado, e é recusado.