Uma discussão interessante sobre a distinção entre retornos de chamada e continuações no SO levou a essa pergunta. Por definição, uma continuação é uma representação abstrata da lógica necessária para concluir um cálculo. Na maioria dos idiomas, isso se manifesta como um procedimento de um argumento para o qual você transmite qualquer valor que precise de processamento contínuo.
Em uma linguagem puramente funcional (onde todas as funções são cidadãos puros e de primeira classe), eu pensaria que uma continuação poderia ser inteiramente modelada como uma função. Afinal, é assim que eu entendi as continuações até esse ponto. No entanto, o mundo está cheio de estado (suspiro) e, portanto, a definição geral não exige que um programa de captura de continuação exiba - ele precisa apenas incluir intenção.
Para ajudar meu entendimento, um exemplo pode ser fornecido em uma linguagem funcional em que a continuação é expressa de uma maneira mais abstrata do que uma função? Eu sei que o Scheme permite que você pegue a continuação atual de uma maneira de primeira classe (call / cc), mas mesmo assim, parece que o procedimento de um argumento passado para chamar / cc recebe simplesmente a continuação atual na forma de outro procedimento de argumento ao qual a função call / cc'd pode aplicar seu resultado.
fonte
Respostas:
tl; dr; O tipo é a abstração abrangente em uma continuação
Uma continuação é o tipo de suas entradas e saídas
A coisa mais próxima que você encontrará de uma continuação não baseada em procedimentos é provavelmente a mônada de continuação em Haskell , pois é expressa como um tipo, para o qual muitas funções podem ser usadas para interagir com o tipo de interrupção, retomada, retorno, etc.
Você pode encapsular esse fechamento em um tipo como o
Cont
tipo em Haskell, onde você obtém a abstração de mônada como uma "abstração de nível superior", e existem outras formas de abstração nas continuações que você obtém quando vê a continuação como um tipo, em vez de simplesmente um procedimento , por exemploEncerramento x Procedimento
No final do dia, você está basicamente certo; uma continuação é um "procedimento", embora eu prefira me referir a ele como um encerramento. Muitas vezes, as continuações são melhor expressas como fechamentos de primeira classe que encerram um ambiente vinculado. Em uma linguagem funcional pura, você pode dizer que isso não é particularmente razoável porque lhe faltam referências; isso é verdade, mas você pode incluir valores e a atribuição única faz com que o valor e a referência sejam exatamente a mesma coisa. Isso dá origem a Haskell:
Um idioma que carece da capacidade de incluir um ambiente vinculativo pode tecnicamente carecer de fechamentos de primeira classe, mas mesmo assim há algum ambiente (geralmente o global) disponível para o fechamento.
Então, eu diria que é mais preciso descrever uma continuação como: Um fechamento sendo usado de uma maneira específica.
Conclusão
Para a pergunta "Uma continuação é implementável de alguma maneira que não seja um procedimento?" Não. Se você não possui funções de primeira classe, não pode ter continuações como tal (sim, os ponteiros de função contam como funções de primeira classe, portanto, alternativamente, o acesso arbitrário à memória pode ser suficiente).
Agora, para a pergunta "Existe alguma maneira de expressar uma continuação de uma maneira mais abstrata do que um procedimento?" Expressá-lo como um tipo fornece uma abstração muito maior, permitindo tratar a continuação de maneiras muito gerais, de modo que você possa interagir com a continuação de muitas outras maneiras além de executá-la.
fonte
Um exemplo que você pode gostar são as corotinas. Por exemplo, as Coroutines de Lua ou os iteradores / geradores de Python ou C # são semelhantes em poder às continuações de uma só vez (continuações que você só pode chamar uma vez), mas a continuação não é explicitamente transformada em função. Em vez disso, você tem maneiras de avançar a corotina até a próxima instrução "yield".
Por exemplo, considere o seguinte programa Python:
É semelhante ao seguinte programa Javascript com retornos de chamada explícitos:
O exemplo de Javascript é meio barulhento, porque cada etapa precisa retornar a próxima continuação, além de retornar o valor gerado (no Python mantém o controle da continuação dentro do ite
fonte