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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top