Passar um subprograma como argumento para outro
Várias motivações
- Implementar funções de ordem maior (característica funcional)
- Funções de ordenação para diferentes elementos
- Funções no modelo callback
- …
Questões de projeto
- Como passar subprogramas? Como verificar seus tipos?
- C/C++ se passa o endereço de uma função
- Exemplo
float (*pfun) (float, int);
- \pause Como definir o ambiente de referenciamento?
→ para linguagens que aceitam subprogramas aninhados
Devemos definir qual o ambiente de referenciamento
Três abordagens
- Vinculação profunda (deep binding)
- Ambiente → onde ocorreu a definição do subprograma
- Equivalente ao vínculo estático do RA
- Vinculação rasa (shallow binding)
- Ambiente → onde ocorreu a chamada do subprograma
- Equivalente ao vínculo dinâmico do RA
- Vinculação arbitrária (ad-hoc binding)
- Ambiente → onde ocorreu a passagem do subprograma
\scriptsize
function sub1() {
var x;
function sub2() {
alert(x); //imprime na tela o valor de x
};
function sub3() {
var x;
x = 3;
sub4 (sub2);
};
function sub4(subx) {
var x;
x = 4;
subx();
};
x = 1;
sub3();
};
\normalsize Qual o valor impresso de x quando usamos?
- Vinculação profunda (vínculo estático)
- Rasa (vínculo dinâmico – quem chama)
- Arbitrária (quem passa)
Closure
- Bloco de código
- Vínculos já estabelecidos (do ambiente de origem)
- Usar variáveis visíveis no momento da sua definição
\pause Utilizadas em linguagens dinâmicas (Lisp, Ruby, …)
- Influência do Modelo Funcional
\pause Exemplo em pseudocódigo {\scriptsize
function makeAdder (x) {
return function(y) {return x + y;}
}
var add10 = makeAdder(10);
var add5 = makeAdder(5);
add10(20); //adiciona 10 a 20
add5(10); //adiciona 5 a 10
\pause Mesmo quando retornado, o vínculo continua existindo