Funções
Uma função é um pedaço de código com nome, que recebe valores e devolve um resultado. Serve para não repetir o mesmo código em vários sítios: se a conta estiver numa função, corriges num lugar só.
Declaração
Seção intitulada “Declaração”fn <nome>(<parâmetros>) <tipo_retorno> { // corpo}Uma função que não retorna valor omite o tipo de retorno:
fn <nome>(<parâmetros>) { // corpo}Repara que o tipo de retorno vem depois da lista de parâmetros, como em Go, e não antes do nome como em C.
Exemplos
Seção intitulada “Exemplos”Função com retorno
Seção intitulada “Função com retorno”fn soma(int a, int b) int { divolvi a + b;}Função sem retorno (void)
Seção intitulada “Função sem retorno (void)”fn saudacao(textu nome) { mostran(f"Olá, {nome}!");}Função de entrada (inisiu)
Seção intitulada “Função de entrada (inisiu)”fn inisiu() { int resultado = soma(3, 4); mostran(resultado);}inisiu é a única função com regras próprias: não pode ter parâmetros nem declarar um tipo de retorno.
Chamada de funções
Seção intitulada “Chamada de funções”soma(10, 20);saudacao("Mundo");int r = soma(1, 2);Os argumentos são ligados aos parâmetros pela posição, não pelo nome: em soma(10, 20), o 10 vai para a e o 20 para b. Não há argumentos com nome nem valores por omissão, por isso tens de passar sempre todos os parâmetros, e com os tipos certos.
divolvi (return)
Seção intitulada “divolvi (return)”Retorna um valor da função. O tipo deve corresponder ao tipo declarado:
fn dobro(int n) int { divolvi n * 2;}O divolvi termina a função ali mesmo: o código escrito depois dele nunca corre.
Numa função sem tipo de retorno, divolvi pode aparecer sem valor para saída antecipada:
fn imprimeSeNaoNegativo(int n) { si n < 0 { divolvi; } mostran(f"{n} não é negativo");}Na prática, um si sem sinon não chega: precisas de um divolvi final fora do si, mesmo que saibas que a condição cobre todos os casos.
Parâmetros são cópias
Seção intitulada “Parâmetros são cópias”Cada parâmetro recebe uma cópia do valor passado. Alterá-lo dentro da função não muda a variável de quem chamou:
fn tenta_mudar(int n) { n = 99;}
fn inisiu() { int x = 1; tenta_mudar(x); mostran(x); // 1, não 99}Vale para tudo, incluindo arrays e moldes, que também são valores. Para alterar algo de quem chamou, devolve o novo valor e atribui-o: x = muda(x);. Referências explícitas (ref) estão planeadas para o futuro.
Arrays como parâmetros e retorno
Seção intitulada “Arrays como parâmetros e retorno”Um parâmetro ou o tipo de retorno pode ser um array de tamanho fixo. O array é copiado, por isso alterá-lo dentro da função não muda o de quem chamou:
fn soma(int[3] v) int { divolvi v[0] + v[1] + v[2];}
fn identidade() int[2][2] { divolvi [[1, 0], [0, 1]];}O tamanho faz parte do tipo: uma função que recebe int[3] não aceita um int[4]. Vê Arrays como valores.
Um molde declarado com molda também se usa como tipo de parâmetro e de retorno, e também é copiado; vê Moldes (molda).
Recursão
Seção intitulada “Recursão”O Kriol suporta recursão e recursão mútua. As funções podem ser chamadas antes da sua declaração no ficheiro:
fn par(int n) bool { si n == 0 { divolvi sin; } divolvi impar(n - 1);}
fn impar(int n) bool { si n == 0 { divolvi nau; } divolvi par(n - 1);}
fn inisiu() { mostran(par(4)); // sin mostran(impar(3)); // sin}Uma função recursiva precisa sempre de um caso que não chama a si mesma, como o n == 0 destes exemplos. Sem ele, a recursão não para e o programa esgota a pilha de 8 MiB que os programas Kriol recebem.
Uma função declara que pode falhar escrevendo : Erru depois do tipo de retorno, e quem a chama trata a falha com tenta ou sinon; vê Erros.
Funções embutidas
Seção intitulada “Funções embutidas”| Função | Descrição |
|---|---|
mostra(...) | Imprime os argumentos, sem nova linha no fim |
mostran(...) | Imprime os argumentos, seguidos de nova linha |
toma() | Lê uma linha de stdin e retorna textu; pode falhar com Erru (termina o programa se não for tratado; vê tenta e sinon) |
konfirma(e), konfirma(e, m) | Verifica que e é verdadeiro; termina se falso, com a mensagem m se existir |
paniku(m) | Termina o programa de imediato com a mensagem m |
sai(), sai(código) | Termina o programa com o código de saída dado, ou 0 sem argumento |
mostra e mostran aceitam vários valores
Seção intitulada “mostra e mostran aceitam vários valores”Ao contrário das funções que escreves, mostra e mostran recebem quantos argumentos quiseres, de tipos diferentes, e escrevem-nos seguidos sem nada entre eles:
textu nomi = "Ana";int idadi = 30;
mostran("Nome: ", nomi, ", idade: ", idadi);// Nome: Ana, idade: 30Sem argumento nenhum, mostran() escreve apenas uma linha vazia, prático para separar blocos de saída:
mostran("primeiro bloco");mostran();mostran("segundo bloco");Isto e uma f-string com os mesmos valores dão o mesmo resultado; escolhe a forma que se lê melhor em cada caso.
Um valor de molde não se pode escrever de uma vez em nenhuma das formas; escreve os campos um a um. Vê Strings e Interpolação.
- Não é permitida a duplicação de funções com o mesmo nome, nem com parâmetros diferentes: não há sobrecarga (overloading).
- Não há parâmetros com valor por omissão nem argumentos passados por nome.
- Os parâmetros são passados por valor.
- A ordem de declaração no ficheiro não afeta a capacidade de chamada entre funções do mesmo ficheiro.
- Uma função não pode ser declarada dentro de outra; todas vivem no topo do ficheiro.
- Cada parâmetro e cada valor devolvido ocupa no máximo 1 MiB, porque vive na pilha.