LUA – Linguagem de Programação – Parte 5

No artigo anterior demos ênfase às informações relacionadas com o uso de concatenação, precedências, variáveis indexadas, tabelas com listas, e registos. O tema deste artigo é o uso das funções.

A finalidade geral de uma função é o de retornar um valor após a execução de sua operação. Na linguagem de programação Lua, uma função poderá retornar um ou mais valores e até mesmo não retornar nenhum valor.

A linguagem Lua faz uso de funções internas e externas. Neste artigo será enfatizado o uso de funções externas.

Funções Internas

Funções internas relacionam-se ao conjunto de recursos existentes e disponíveis nas bibliotecas internas de uma linguagem.

Lua possui como conjunto de bibliotecas padrão, as bibliotecas:

  • básica;
  • de pacotes;
  • de cadeias de caracteres;
  • manipulação de tabelas;
  • funções matemáticas;
  • entrada e saída;
  • facilidades do sistema operacional;
  • facilidades de depuração.

Além das funções de bibliotecas padrão, há outras funções que poderão ser facilmente consultadas no site da linguagem Lua: www.lua.org/manual/5.1/pt/manual.html.

Nos artigos anteriores, em alguns dos exemplos de programas apresentados, foi utilizada a função string.format(), que se caracteriza por ser uma função da biblioteca de cadeias de caracteres.

O programa seguinte faz a apresentação de alguns efeitos relacionados à string "Linguagem Lua" definida para a variável FRASE. Serão apresentados o tamanho da frase (string.len), em caracteres minúsculos (string.lower), em caracteres maiúsculos (string.upper) e em caracteres invertidos (string.reverse).

-- início do programa FUNCAO 1
  
  FRASE = "Linguagem Lua"

  print(string.len(FRASE))
  print(string.lower(FRASE))
  print(string.upper(FRASE))
  print(string.reverse(FRASE))
  
-- fim do programa FUNCAO 1

De seguida, escreva o código do programa num editor de texto, gravando-o com o nome funcao01.lua e execute-o com a linha de comando lua 5.1 funcao01.lua.

Outra biblioteca padrão muito requisitada é a biblioteca de funções matemáticas onde se destacam funções para diversos cálculos matemáticos. O programa seguinte faz a apresentação de alguns cálculos matemáticos obtidos a partir de funções matemáticas, tais como: co-seno, seno, tangente, raiz quadrada e inteiro do valor 1.12.

-- início do programa FUNCAO 2

  VALOR = 1.12

  print(math.cos(VALOR))
  print(math.sin(VALOR))
  print(math.tan(VALOR))
  print(math.sqrt(VALOR))
  print(math.floor(VALOR))

-- fim do programa FUNCAO 2

De seguida, escreva o código num editor de texto, gravando-o com o nome funcao02.lua e execute-o com a linha de comando lua 5.1 funcao02.lua.

Funções Externas

Funções externas são um conjunto de funcionalidades que podem ser definidos pelo próprio programador. A linguagem Lua oferece alguns recursos operacionais muito atraentes no uso de funções definidas pelo programador.

Funções externas podem ser utilizadas com ou sem passagens de parâmetros e podem também ser usadas como comandos quando se desejar simular operações equivalentes ao uso de sub-rotinas (procedimentos em linguagem Pascal).

O programa seguinte apresenta o resultado do quadrado de um valor lido via teclado.

-- início do programa FUNCAO 3

  function QUADRADO()
    QUAD = VLR * VLR
    return QUAD
  end

  VLR = io.read("*number")
  print(QUADRADO())

-- fim do programa FUNCAO 3

Escreva o código num editor de texto, gravando-o com o nome funcao03.lua e execute-o com a linha de comando lua 5.1 funcao03.lua.

Em relação ao programa funcao03.lua, este após a entrada do valor na variável VLR faz a chamada da função QUADRADO() que por sua vez pega o valor atribuído à variável VLR, calcula o quadrado, armazena o seu resultado na variável QUAD, o qual é pela instrução return QUAD devolvido como resultado para a função QUADRADO(). Observe que a definição de uma função é feita com os comandos function e end.

No programa funcao03.lua há outro factor a ser considerado, sendo o uso das variáveis VLR e QUAD como variáveis globais.

As variáveis utilizadas na linguagem Lua caracterizam-se por poderem ser variáveis globais ou locais, além de serem também utilizadas como campos de tabela como mostrado no artigo anterior.

Uma variável global possui visibilidade que lhe confere a capacidade de ser vista por todo o programa, incluindo a parte principal e as funções. Quando uma variável é usada e definida num programa Lua, esta é por padrão considerada global, a menos que seja explicitamente definida como local por meio do comando local.

Por exemplo, ao olhar para o código do programa funcao03.lua nota-se que a variável VLR é citada tanto na parte principal do programa como na função. Desta forma, esta variável deverá ser global, mas a variável QUAD é usada apenas no código da função. Assim sendo, esta variável não tem a necessidade de ser global, podendo ser definida como variável local. Desta forma, observe o código seguinte.

-- início do programa FUNCAO 4

  function QUADRADO()
    local QUAD = VLR * VLR
    return QUAD
  end

  VLR = io.read("*number")
  print(QUADRADO())

-- fim do programa FUNCAO 4 

Escreva o código de programa num editor de texto, gravando-o com o nome funcao04.lua e execute-o com a linha de comando lua 5.1 funcao04.lua.

Note que no programa funcao04.lua ocorre o uso do comando local antes da variável QUAD. Esta instrução fez com que QUAD seja uma variável local. Desta forma, ocorre um consumo menor de memória, pois após a conclusão da execução da função a variável QUAD é eliminada da memória.

Outra possibilidade de uso de funções em Lua é o uso de funções com passagem de parâmetros. Considere o seguinte programa que solicita a entrada de um valor numérico e apresenta como resultado o factorial do valor fornecido.

-- início do programa FUNCAO 5

    function FACTORIAL(N)
      local I, FAT
      FAT = 1
      for I = 1, N do
        FAT = FAT * I
      end
      return FAT
    end

  VLR = io.read("*number")
  print(FACTORIAL(VLR))

-- fim do programa FUNCAO 5

Escreva o código de programa num editor de texto, gravando-o com o nome funcao05.lua e execute-o com a linha de comando lua 5.1 funcao05.lua.

O programa funcao05.lua utiliza variáveis locais no código da função FATORIAL(N), além do uso do parâmetro N que define o valor máximo de execução do ciclo for. Outro detalhe no código da função é o uso do limite do ciclo como sendo I = 1, N diferente de I = 1, N, 1. O uso do valor 1 após a definição de N é opcional, sendo obrigatório apenas quando o passo da contagem for maior que 1.

Um detalhe no uso de funções que deve ser considerado é em relação ao uso de return para que o valor calculado seja retornado. Este comando é de certa forma opcional, pois aquando da sua ausência, a função não dará retorno de um valor. Neste caso, a função terá um comportamento semelhante à definição de procedimentos na linguagem Pascal.

Normalmente funções sem retorno exigem o uso de variáveis globais.

O programa seguinte apresenta o resultado do cálculo do factorial de um número por meio de uma função que não retorna valor.

-- início do programa FUNCAO 6

    function FACTORIAL(N)
      local I, FAT
      FAT = 1
      for I = 1, N do
        FAT = FAT * I
      end
      print(FAT)
    end

  VLR = io.read("*number")
  FACTORIAL(VLR)

-- fim do programa FUNCAO 6

Escreva o código de programa num editor de texto, gravando-o com o nome funcao06.lua e execute-o com a linha de comando lua 5.1 funcao06.lua. Observe junto ao programa funcao06.lua que o resultado da operação é impresso dentro do código da função.

Há uma forma de definição de função em Lua onde se associa a acção da função ao nome de uma variável. Essa forma de uso é também denominada função anónima.

O programa seguinte apresenta este modo de operação. Observe os detalhes de uso da linha de código FACTORIAL = function(N).

-- início do programa FUNCAO 7

    FACTORIAL = function(N)
      local I, FAT
      FAT = 1
      for I = 1, N do
        FAT = FAT * I
      end
      return FAT
    end

  VLR = io.read("*number")
  print(FACTORIAL(VLR))

-- fim do programa FUNCAO 7

Escreva o código de programa num editor de texto, gravando-o com o nome funcao07.lua e execute-o com a linha de comando lua 5.1 funcao07.lua.

A definição de uma função assim como uma variável também poderá ser local. Portanto, observe o uso do comando local antes da definição da função no código seguinte.

-- início do programa FUNCAO 8

    local function FACTORIAL(N)
      local I, FAT
      FAT = 1
      for I = 1, N do
        FAT = FAT * I
      end
      return FAT
    end

  VLR = io.read("*number")
  print(FACTORIAL(VLR))

-- fim do programa FUNCAO 8

Escreva o código de programa num editor de texto, gravando-o com o nome funcao08.lua e execute-o com a linha de comando lua 5.1 funcao08.lua.

Parâmetros Arbitrários

Nos códigos de programas funcao05.lua e funcao06.lua foi utilizado o conceito de passagem de parâmetros que também podem ser referenciados como argumentos.

É importante saber que a linguagem Lua não opera com passagem de parâmetro por referência, apenas faz uso de passagem de parâmetro por valor. No entanto, o código de uma função escrito em Lua pode retornar um número arbitrário de parâmetros.

-- início do programa FUNCAO 9

   function QUANTIDADE(N)
     if (N == 1) then
       return "UM"
     end
     if (N == 2) then
       return "UM", "DOIS"
     end
     if (N == 3) then
       return "UM", "DOIS", "TRES"
     end
   end

  VLR = io.read("*number")
  print(QUANTIDADE(VLR))

-- fim do programa FUNCAO 9

Escreva o código de programa num editor de texto, gravando-o com o nome funcao09.lua e execute-o com a linha de comando lua 5.1 funcao09.lua.

Observe que ao ser executado o código do programa funcao08.lua o retorno dependerá do valor fornecido como parâmetro para a função QUANTIDADE(N).

Outra forma de uso de arbitrariedade de parâmetros é quando os parâmetros a serem usados são indefinidos. Observe no código seguinte a definição de um parâmetro arbitrário por meio da definição de três pontos (…) que caracteriza-se por ser a definição de uma expressão do tipo vararg

-- início do programa FUNCAO 10

    local function FACTORIAL(...)
      local I, FAT
      FAT = 1
      for I = 1, ... do
        FAT = FAT * I
      end
      return FAT
    end

  VLR = io.read("*number")
  print(FACTORIAL(VLR))

-- fim do programa FUNCAO 10

Escreva o código de programa num editor de texto, gravando-o com o nome funcao10.lua e execute-o com a linha de comando lua 5.1 funcao10.lua.

Uma expressão vararg pode ser utilizada quando definida dentro de uma função que possua um número variável de argumentos. Este tipo de operação não ajusta a sua lista de parâmetros. Ao invés disso, pega em todos os parâmetros extras, fornecendo-os à função em uso por meio de uma expressão vararg. O valor desta expressão é uma lista de todos os argumentos extras correntes, semelhante a uma função com retorno de múltiplos valores.

Recursividade

Não há como não falar de uso de funções sem considerar o efeito de recursividade. Neste sentido, a linguagem Lua também oferece tal recurso. Vale a pena lembrar que o efeito de recursividade é a capacidade que uma função possui de chamar a si própria para efectivar certo cálculo. O programa seguinte demonstra o uso de função recursiva na linguagem Lua.

-- início do programa FUNCAO 11

  local function FACTORIAL(N)
    if (N <= 1) then
      return 1
    else
      return FACTORIAL(N-1)*N
    end
  end

  VLR = io.read("*number")
  print(FACTORIAL(VLR))

-- fim do programa FUNCAO 11

Escreva o código de programa num editor de texto, gravando-o com o nome funcao11.lua e execute-o com a linha de comando lua 5.1 funcao11.lua. Note junto ao programa funcao11.lua o uso da linha de instrução return onde encontra-se FACTORIAL(N-1)*N a chamada recursiva da função FACTORIAL().

Conclusão

Neste artigo foi dada atenção às acções de processamento com uso de funções criadas com a linguagem de programação Lua. O conteúdo aqui exposto é introdutório, uma vez que o uso e criação de funções é um tema extenso e para o seu domínio é necessário tempo de dedicação e estudo.

No próximo artigo será tratado o assunto de uso de arquivos.

Publicado na edição 25 (PDF) da Revista PROGRAMAR.