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.