Slide 33 de 74

func e proc

proc grow(vec: mut Str[dyn], tag: Str): void {
	append(vec, tag)
}

// Um func pode chamar um proc — sobre armazenamento próprio.
func tagged(base: Str[], tag: Str): Str[dyn] {
	mut Str[dyn] out = []
	for each b in base {
		append(out, b)
	}
	grow(out, tag)
	return out
}

proc main(): void {
	mut Str[dyn] tags = ["bee"]
	echo tagged(tags, "hive")     // ["bee", "hive"]
	echo tags                     // ["bee"] — o func não mudou nada nosso
	grow(tags, "wax")
	echo tags                     // ["bee", "wax"] — o proc mudou
}

Ambos podem fazer qualquer coisa que um programa faz — echo, arquivos, a rede, iniciar threads — e ambos podem chamar qualquer um. Eles diferem em uma coisa: um func não pode declarar um parâmetro mut, então nunca pode escrever em um armazenamento que quem o chamou consiga ver. Ele ainda pode chamar um proc, porque um parâmetro mut precisa receber uma variável mut, e as únicas dentro de um func são as dele. Uma variável mut passada a um func chega como uma cópia imutável.

Então um func é uma promessa em que um leitor pode se apoiar — chamá-lo não muda nada seu — e um proc é onde escrever pelo armazenamento de quem chamou é permitido. Programas começam em um proc, o main. Como uma chamada roda, esperada ou numa thread própria, é decidido onde ela é chamada, nunca onde é declarada.