5.7. Criação de funções

Para melhorar os nossos códigos evitando repetição de códigos semelhantes, dividindo melhor cada parte e garantir uma melhor manutenção, podemos criar nossas próprias funções. Afinal, até aqui você utilizou diversas funções das linguagens, mas e se criássemos as nossas próprias funções? Arthur, mas e procedimentos? Procedimentos são funções que não retornam nenhum valor, mas esqueça esse termo, é um termo antigo, hoje procedimentos são chamados de função. É tudo função, ok?!!

Se criarmos nossas próprias funções, podemos ter diversos benefícios, como:

  • reuso de código, evitando códigos duplicados;

  • separar melhor as funções e ajudar na manutenção do código;

  • uso da ideia de dividir para conquistar, onde divide o problema em pedaços pequenos (funções) para formar o código completo etc;

Assim, uma função tem uma assinatura com três partes:

  • Uma valor de retorno;

  • um identificador; e

  • os argumentos.

Sua estrutura é mais ou menos assim:

tipoRetorno nomeFuncao(argumento1, argumento2, argumentoN)

Essa estrutura é chamada de assinatura da função. A função irá receber os argumentos como variáveis internas a função da forma que quiser e ao final irá retornar um valor do tipo tipoRetorno. Por exemplo, imagine a função com a seguinte assinatura de função inteiro some(numero1, numero2), está ideia de função irá somar dois números e retornar a sua soma. E poderia ser implementada assim:

inteiro some(numero1, numero2){
inteiro soma
soma = numero1 + numero2
retorne soma
}

E poderia ser utilizada de várias formas, como estas abaixo, sempre passando dois números:

some(2, 3)
//ou
some(num1, 3)
// ou
some(idade, 1)
// ou
some(idade, num)

Perceba que a estrutura de uma função varia de linguagem para linguagem e por isso nas próximas seções apresento como é em cada linguagem.

Além disso, podemos utilizar as funções para criar um loop, uma repetição, usando uma ideia chamada de Recursão. A recursão ocorre quando uma função chama a si mesma dentro de seu código, claro que se ela se chamar irá fazer isso para sempre, porém para evitar isso colocar umas condição de parada onde ela para de se chamar caso algo seja verdadeiro.

Por exemplo. Veja a ideia de função abaixo.

inteiro some(num1, num2){
inteiro soma
soma = num1 + num2
retorne some(soma, num1)
}

Essa função não irá fazer nada relevante, mas entrará em loop infinito, pois sempre irá chamar uma nova função some passando o valor da soma e o primeiro valor recebido como parâmetro da função, o parâmetro da função é o valor passado para o argumento da função. Nesse caso, devemos colocar uma condição para acabar com o loop. Mais abaixo apresento um exemplo melhor para ilustrar a ideia de recursão. Antes quero falar mais sobre a recursão, ela é um recurso muito útil, mas perigoso. Ao criar um loop onde ele armazena os valores utilizados das funções chamadas na recursão? São armazenados em uma estrutura chamada Pilha de execução, essa pilha tem um limite de memória, portanto caso ela exceda você receberá um erro de stack overflow (estouro de pilha, em português), como o nome daquele fórum muito importante.

Código de fibonnacii em loop e recursao AQUI

Boas práticas em Identificadores de Funções

Há diversas formas de se escrever o identificador de uma função, primeiro devemos usar as formas apresentadas no Capítulo \ref{chap:padrao-nomes}, porém resta saber como formar esses identificadores. Abaixo temos as formas mais usadas:

  • Nome no infinitivo: exemplo: somar(), gerarDados();

  • Nome no imperativo: exemplo: some(), gereDados();

  • Nome no Imperativo e em inglês: exemplo: sum(), generateData();

Como vimos nos primeiros capítulos, a programação antes de qualquer paradigma é imperativa, ou seja, você manda o computador realizar tarefas, por isso recomendo que use o imperativo, independente do idioma, porém em inglês é muito mais recomendado e correto, pois as linguagens são escritas em inglês. Além disso, há quem confunda e acredite que em inglês usam o infinitivo, como sum(), para ser no infinitivo teria que ser toSum(), portanto sum() está no imperativo, logo as formas imperativas podem ser consideradas mais corretas.