Como criar uma função recursiva em Cobol?

A codificação de funções em COBOL foi padronizada pela revisão ISO 2002 e está disponível em diversos compiladores. O GnuCOBOL também oferece esse recurso pelo menos desde a versão 2.0, mas ainda possui alguns bugs conhecidos, inclusive na última versão 3.1.

Neste artigo vou codificar uma função recursiva e mostrar como contornar um desses bugs.

A função calcula o fatorial de um número informado via argumento. Só para recordar, o fatorial de um número inteiro “n” é o produto de “n” vezes todos os inteiros positivos menores que “n”, ou seja:

n! = n x (n-1) x (n-2) x (n-3) x ... x 1

Ou num caso prático…

5! = 5 x 4 x 3 x 2 x 1 = 120

…que é a mesma coisa que escrever…

5! = 5 x 4!

Ou seja, uma das propriedades do fatorial é que…

n! = n x (n - 1)!

…então vamos codificar uma função que subtrai 1 do argumento recebido e chama a si mesma com esse novo argumento:

identification division.
function-id. FATORIAL.

data division.
working-storage section.
77 wt-fatorial-1 usage binary-long.

linkage section.
01 lk-n          usage binary-long.
01 lk-fatorial   usage binary-long.

procedure division using by reference lk-n returning lk-fatorial.
principal.
    if lk-n = 1 
        move 1 to lk-fatorial 
    else 
        move FATORIAL(lk-n - 1) to wt-fatorial-1 
        compute lk-fatorial = lk-n * wt-fatorial-1 
    end-if 
    goback.
end function FATORIAL.

Repare que a função chama a si mesma passando o valor do argumento recebido (lk-n) menos 1 e em seguida multiplica o argumento original pelo resultado da função.

Em tese qualquer variável numérica, inclusive USAGE DISPLAY, poderia ser passada para a função, mas um bug do GnuCOBOL faz com que a função só funcione com variáveis BINARY-LONG.

Outra restrição desse compilador é que a biblioteca de run-time só consegue localizar a função se seu nome for codificado com letras maiúsculas.

O programa principal, que chama a função, fica assim…

identification division.
program-id. gtc015.

environment division.
configuration section.
repository.
    function FATORIAL.

data division.
working-storage section.
77 wt-n usage binary-long.

procedure division.
main.
    display "Entre com um numero inteiro positivo:"
    accept wt-n from console
    if wt-n not = zeros
        display wt-n "!=" FATORIAL(wt-n)
    end-if
    stop run.

A função que se vai chamar precisa ser declarada no parágrafo REPOSITORY da CONFIGURATION SECTION. Quando executado, o programa principal mostra o seguinte:

[aeisxpad ~/cbl]$ gtc015
Entre com um numero inteiro positivo:
5
000000005!=000000120

Durante muito tempo a falta de funções no COBOL foi alvo de críticas. A incorporação desse recurso em compiladores que aderiram ao padrão 2002 deixa o programa mais elegante e aumenta a sua legibilidade.


Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *