Para impedir esse tipo de erro, melhor seria garantir a definição de VALOR aconteça o que acontecer. Tal garantia pode ser conseguida de diversas formas. Desde a declaração do termo logo no início da função, ou mesmo usando if para realizar testes e determinar a melhor declaração possível. Veja o exemplo:
function VALOR = media (a,b)
VALOR = 0;
if (a<100)
VALOR = (a + b)/2;
endif
endfunction
Perceba que no caso anterior nós já começamos definindo um valor para VALOR. Dessa forma, se o if não executar seu código interno, mesmo assim a função retornará um valor. E não haverá erro.
Claro que uma outra forma de lidar com o assunto é fazendo testes, e o uso de if pode ser interessante.
Outra característica muito interessante disponível no Octave é o uso de funções de uma única linha. Por exemplo, digamos que você usará muitas vezes a expressão F(X) = exp(X) - 2*X. O porquê da necessidade de tal cálculo? Vai saber, mas vamos apenas supor que você precisará usar diversas e diversas vezes essa expressão. Assim, em Octave podemos abreviar tal tarefa usando o código.
F = inline("exp(X) + 2*X");
Dessa forma, toda vez que precisar calcular a exponencial de um número menos o seu dobro, basta fazer F(X).
Retornando mais de um valor
É claro que talvez desejamos receber mais de um valor vindo de certa função. Muitas linguagens de programação não permitem isso, mas no Octave é possível: uma função pode retornar mais de um valor. Eis a sintaxe:
function [LISTA-VALOR] = NOME (ARGUMENTOS)
codigoParaExecutar
endfunction
Onde há LISTA-VALOR, entra os nomes das variáveis que a função retornará os valores. Abaixo, mais um exemplo de uso.
function [media, soma] = operacoes (a,b)
media = 0;
soma = 0;
if (a<100)
soma = (a + b);
media = (a + b)/2;
endif
endfunction
Criando sua própria biblioteca
O mais interessante e útil referente ao uso de funções é a possibilidade de utilização em diversos programas. Isso mesmo! Você pode escrever uma função, salvá-la em um arquivo, e utilizá-la em todo programa que escrever. Cada linguagem usa uma forma de implementar essa característica. Em Octave, você deve escrever cada função em um arquivo texto, e salvar com a extensão " .m ". Dessa forma, quando escrever um programa poderá chamar uma função escrita previamente como se fosse parte do programa atual.
Para usar uma função dessa forma, não é preciso carregar a função antes do uso. Por exemplo, não é preciso carregar a função no início do programa. Você, da forma mais simples possível, indica a função e suas definições onde o Octave a usará. E o que acontece internamente no Octave?
Quando o Octave encontra a chamada de uma função, a primeira coisa feita por ele é procurar por variáveis ou funções já compiladas e na sua própria tabela. Se a função não estiver lá, então o Octave procura em uma lista de diretórios (o chamado "path") por arquivos com a terminação " .m " com o mesmo nome da função indicada no código do programa. Uma vez encontrado o arquivo, seu conteúdo é lido, e se uma função estiver definida será compilada e executada. Para ver o path de seu Octave, use o comando path sem opções.
É claro que você pode acrescentar diretórios ao path. Por exemplo, podemos criar um diretório onde guardaremos todos os arquivos com nossas funções. Para acrescentar tal diretório ao path do Octave, usamos o comando addpath. Abaixo, veja como incluiríamos o diretório /home/usuário/Octave/funcoes ao path do Octave.
addpath("~/Octave/funcoes")
Outra característica interessante: nada impede de usarmos funções dentro de funções. Ou seja, podemos usar subfunções. Ao definirmos uma função, podemos escrever outras funções dentro do código. Dessa forma, as subfunções se tornam funções "locais", não acessadas por outros trechos do código do programa principal.