Fechamento (informática)
Na informática, um fechamento é uma função que tem um ambiente próprio. Neste ambiente, há pelo menos uma variável vinculada (um nome que tem um valor, como um número, por exemplo). O ambiente do fechamento mantém as variáveis vinculadas na memória entre os usos do fechamento.
Peter J. Landin deu a esta idéia o nome de fechamento em 1964. A linguagem de programação Scheme tornou os fechamentos populares depois de 1975. Muitas linguagens de programação feitas depois dessa época têm fechamentos.
As funções anônimas (funções sem nome) às vezes são chamadas erroneamente de fechamentos. A maioria dos idiomas que têm funções anônimas também têm fechamentos. Uma função anônima também é um fechamento se ela tiver um ambiente próprio com pelo menos uma variável vinculada. Uma função anônima sem ambiente próprio não é um fechamento. Um fechamento nomeado não é anônimo.
Fechamentos e funções de primeira classe
Os valores podem ser números ou algum outro tipo de dados, tais como letras, ou estruturas de dados compostas de peças mais simples. Nas regras de uma linguagem de programação, os valores de primeira classe são valores que podem ser dados a funções, retornados por funções e vinculados a um nome variável. Funções que tomam ou retornam outras funções são chamadas funções de ordem superior. A maioria das linguagens que têm funções como valores de primeira classe também têm funções de ordem mais alta e fechamentos.
Por exemplo, veja a função Esquema a seguir:
Neste exemplo, a expressão lambda (lambda (livro) (>= (livro-venda livro) limiar))
faz parte da função best-seller-books.
Quando a função é executada, o Scheme deve fazer o valor da lambda. Ele faz isso fazendo um fechamento com o código para a lambda e uma referência à variável limiar
, que é uma variável livre dentro da lambda. (Uma variável livre é um nome que não está vinculado a um valor).
A função de filtro
então executa o fechamento em cada livro da lista para escolher quais livros devem retornar. Como o fechamento em si tem uma referência ao limite
, o fechamento pode usar esse valor cada vez que o filtro
executa o fechamento. A própria função de filtro
pode ser escrita em um arquivo completamente separado.
Aqui está o mesmo exemplo reescrito em ECMAScript (JavaScript), outra linguagem popular com suporte para fechamentos:
ECMAScript usa a palavra função
aqui em vez de lambda
, e o método Array.filter
no lugar da função de filtro
, mas caso contrário o código faz a mesma coisa da mesma forma.
Uma função pode criar um fechamento e devolvê-lo. O exemplo a seguir é uma função que retorna uma função.
Em esquema:
Em ECMAScript:
O ambiente de fechamento mantém as variáveis f
e dx
após o retorno da função de fechamento (derivada
). Em idiomas sem fechamentos, estes valores seriam perdidos após os retornos da função de fechamento. Em idiomas com fechamentos, uma variável vinculada deve ser mantida na memória enquanto qualquer fechamento a tiver.
Um fechamento não precisa ser formado usando uma função anônima. A linguagem de programação Python, por exemplo, tem suporte limitado para funções anônimas, mas tem fechamentos. Por exemplo, uma forma de implementar o exemplo ECMAScript acima em Python é:
Neste exemplo, a função chamada gradiente faz um fechamento junto com as variáveis f e dx. A função de fechamento externo chamada derivada retorna este fechamento. Neste caso, uma função anônima também funcionaria.
Python deve freqüentemente usar funções nomeadas, pois suas expressões lambda podem conter apenas outras expressões (código que retorna um valor) e não declarações (código que tem efeitos, mas nenhum valor). Mas em outras línguas, tais como Scheme, todo código retorna um valor; em Scheme, tudo é uma expressão.
Usos dos fechamentos
Os fechamentos têm muitos usos:
- Os projetistas de bibliotecas de software podem permitir que os usuários personalizem o comportamento, passando os fechamentos como argumentos para funções importantes. Por exemplo, uma função que classifica valores pode aceitar um argumento de fechamento que compara os valores a serem classificados de acordo com um critério definido pelo usuário.
- Como os fechamentos atrasam a avaliação - ou seja, eles não "fazem" nada até que sejam chamados - eles podem ser usados para definir estruturas de controle. Por exemplo, todas as estruturas de controle padrão do Smalltalk, incluindo ramos (if/then/else) e loops (while and for), são definidas usando objetos cujos métodos aceitam fechamentos. Os usuários também podem definir facilmente suas próprias estruturas de controle.
- Podem ser produzidas múltiplas funções que se fecham sobre o mesmo ambiente, permitindo que se comuniquem de forma privada alterando esse ambiente (em idiomas que permitem a atribuição).
Em esquema
- Os fechamentos podem ser usados para implementar sistemas de objetos.
Nota: Alguns alto-falantes chamam qualquer estrutura de dados que liga um ambiente lexical de fechamento, mas o termo geralmente se refere especificamente a funções.
Perguntas e Respostas
Q: O que é uma closure na ciência da computação?
R: Uma closure é uma função que tem um ambiente próprio.
P: O que contém o ambiente de uma closure?
R: O ambiente de uma closure contém pelo menos uma variável vinculada.
Q: Quem deu o nome à ideia de closure?
R: Peter J. Landin deu o nome à ideia de closure em 1964.
P: Qual linguagem de programação popularizou as closures depois de 1975?
R: A linguagem de programação Scheme tornou as closures populares depois de 1975.
P: Funções anônimas e closures são a mesma coisa?
R: Às vezes, as funções anônimas são erroneamente chamadas de closures, mas nem todas as funções anônimas são closures.
P: O que torna uma função anônima uma closure?
R: Uma função anônima é uma closure se tiver um ambiente próprio com pelo menos uma variável vinculada.
P: Uma closure nomeada é anônima?
R: Não, uma closure nomeada não é anônima.