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:

; devolver uma lista de todos os livros com pelo menos THRESHOLD cópias vendidas. (definir (limite de livros mais vendidos) (filtro (limite lambda (livro) (>= (livro de vendas)))      lista de livros))

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:

// Devolver uma lista de todos os livros com pelo menos 'threshold' de cópias vendidas. função bestSellerBooks(threshold) { devolver bookList. filter( function(book) { devolver book. vendas >= threshold; } ); }

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:

(definir (derivada f dx) (lambda (x) (/ (- (f (+ x dx))) (f x)) dx)))

Em ECMAScript:

// Retorna uma função que se aproxima da derivada de f // usando um intervalo de dx, que deve ser adequadamente pequeno. function derivative(f, dx) { return function(x) { return (f(x + dx) - f(x)) / dx;    }; }; }

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 é:

# Retorna uma função que se aproxima da derivada de f # usando um intervalo de dx, que deve ser adequadamente pequeno. def derivada(f, dx): def gradiente(x): retorno (f(x + dx) - f(x)) / dx gradiente de retorno

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.

def derivado(f, dx): retorno lambda x: (f(x + dx) - f(x)) / dx

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

(definir foo #f) (definir bar #f) (let ((secret-message "none")) (set! foo (lambda (msg) (set! secret-message msg))) (set! bar (lambda () secret-message)) (display (bar)); imprime "none" (newline) (foo "meet me by the docks at midnight") (display (bar)); imprime "meet me by the docks at midnight" (meet me by the docks at midnight)
  • 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.


AlegsaOnline.com - 2020 / 2022 - License CC3