Clausura (ciência da computação)
Em ciência da computação e na programação uma clausura (do inglês closure) é uma função que referencia variáveis livres no contexto léxico. Uma clausura ocorre normalmente quando uma função é declarada dentro do corpo de outra, e a função interior referencia variáveis locais da função exterior. Em tempo de execução, quando a função exterior é executada, então uma clausura é formada, que consiste do código da função interior e referências para quaisquer variáveis no âmbito da função exterior que a clausura necessita.
Utilização
As clausuras são utilizadas para:
- Bibliotecas de software podem permitir que os usuários customizem o comportamento passando clausuras como argumentos às funções importantes. Por exemplo, uma função que classifique valores pode aceitar um argumento de clausura que compare os valores a ser classificados de acordo com um critério definido pelo próprio usuário.
- As funções múltiplas podem ser produzidas num mesmo ambiente, permitindo-as de se comunicar confidencialmente.
- Sistemas de objetos podem ser construídos com clausuras. Por exemplo, Scheme padrão não suporta programação orientada a objetos, mas há sistemas de objetos construídos para essa linguagem de programação com recurso a clausuras.
Exemplos
- Ruby:
def new_counter i = 0 lambda { i += 1 } end c1 = new_counter puts c1.call puts c1.call puts c1.call puts c1.call puts c1.call
- Lisp:
(defun foo () (let ((counter 0)) ;; a função anônima a seguir é definida no escopo de counter, ;; por isso foo retornará uma clausura (lambda () (setf counter (+ 1 counter)) counter))) (setf counter-1 (foo)) (setf counter-2 (foo)) (funcall counter-1) ==> 1 (funcall counter-1) ==> 2 (funcall counter-2) ==> 1
- Javascript:
function novoContador () { var i = 0; return function () { // função anônima i += 1; return i; } } c1 = novoContador(); alert(c1()); // 1 alert(c1()); // 2 alert(c1()); // 3 alert(c1()); // 4 alert(c1()); // 5
- PHP:
function newCounter() { $i=0; return function() use (&$i) { return ++$i; }; } $countMe = newCounter(); print($countMe()); print($countMe()); print($countMe()); print($countMe());
- Python:
>>> def foo(start=0): ... counter = [start] # counter is 1-element array ... def bar(): ... counter[0] = counter[0] + 1 ... return counter[0] ... return bar ... >>> count = foo(10) >>> count() 11 >>> count() 12
- Scheme:
(define (foo) (let ((counter 0)) (lambda () (set! counter (+ 1 counter)) counter))) (define counter-1 (foo)) (define counter-2 (foo)) (counter-1) ==> 1 (counter-1) ==> 2 (counter-1) ==> 3 (counter-2) ==> 1
Na internet
- Foundations of Actor Semantics Will Clinger, MIT Mathematics Doctoral Dissertation. June 1981.
- Martin Fowler sobre Closure