Ajuda com vento dinâmico e chamada/cc
-
27-09-2019 - |
Pergunta
Estou tendo alguns problemas para entender o comportamento do seguinte programa de esquema:
(define c
(dynamic-wind
(lambda () (display 'IN)(newline))
(lambda () (call/cc (lambda (k)
(display 'X)(newline)
k)))
(lambda () (display 'OUT)(newline))))
Pelo que entendi, C estará vinculado à continuação criada logo antes "(Display 'x)".
Mas usar C parece se modificar! A defina acima impressões (como eu esperava) em, x e out:
IN
X
OUT
E é um procedimento:
#;2> c
#<procedure (a9869 . results1678)>
Agora, eu esperaria que, quando fosse chamado novamente, X seria impresso e não é!
#;3> (c)
IN
OUT
E agora C não é mais um procedimento, e uma segunda invocação de C não funciona!
#;4> c ;; the REPL doesn't answer this, so there are no values returned
#;5> (c)
Error: call of non-procedure: #<unspecified>
Call history:
<syntax> (c)
<eval> (c) <--
Eu esperava que cada invocação para (c) ficasse a mesma coisa - imprima, x e fora. o que estou perdendo?
Solução
Executar isso na raquete é um pouco mais útil:
-> (define c
(dynamic-wind
(lambda () (display 'IN)(newline))
(lambda () (call/cc (lambda (k)
(display 'X)(newline)
k)))
(lambda () (display 'OUT)(newline))))
IN
X
OUT
-> c
#<continuation>
-> (c)
IN
OUT
define-values: context (defining "c") expected 1 value, received 0 values
-> (c 99)
IN
OUT
-> c
99
Observe especificamente isso c
fica ligado a um valor de continuação - porque sua expressão retorna k
como o valor. E k
por si só é a continuação da expressão de valor, o que significa que essa continuação é aquela que espera para obter um valor para estar ligado a c
. Portanto, invocá -lo requer um único valor, conforme exige a Racket, o que ajuda a esclarecer o que acontece aqui (o esquema do MIT parece tratá -lo silenciosamente como não especificado). De qualquer forma, aplicar essa continuação em 99 significa que o valor de retorno dessa expressão é 99 - então você volta ao contexto (impressão IN
) e retornar 99 ser obrigado a c
, e imprimir OUT
na sua saída. Você agora modificou c
Para ter esse 99, para que você não possa chamá -lo pela terceira vez.