Clojure tem continuações / corotinas / etc?

20

Comecei a programar com Python e fiquei realmente confuso com conceitos como corotinas e fechamentos.

Agora, acho que os conheço em algum nível superficial, mas nunca senti esse momento de "iluminação", então escolhi aprender Clojure. Comprei o livro de Stuart Halloway e é bom, mas, quando olhei para o índice, não havia palavras como corotina ou continuação. Eu pesquisei eles, mas também não há nada lá.

Então, minha pergunta é:

O Clojure possui continuações ou corotinas para executar tarefas como ping-ponging sem sobrecarga de pilha?

Exemplo de Python (embora o Python padrão não suporte uma versão completa dessa corotina simétrica):

def ping():
  while 1:
   print "ping"
   function to switching to pong

def pong():
  while 1:
   function to switching to ping
   print "pong"
Novato
fonte

Respostas:

20

O Clojure não possui call / cc, mas você não deseja continuações não limitadas de qualquer maneira.

Argumentamos call/cccomo um recurso da linguagem principal, como a operação de controle distinta para implementar o relegamento nativo de todos os outros para as bibliotecas. O primitivo call/ccé uma abstração ruim - em vários significados de 'ruim' mostrado abaixo - e sua captura da continuação de todo o programa não é praticamente útil. A única recompensa pelo trabalho árduo de capturar toda a continuação com eficiência é um trabalho mais difícil de contornar a captura de toda a continuação. Tanto os usuários quanto os implementadores são melhor atendidos com um conjunto de primitivas de controle bem escolhidas, de vários graus de generalidade, com interações bem pensadas ...

... Oferecer call/cccomo um recurso central de controle em termos dos quais todas as outras instalações de controle devem ser implementadas acaba sendo uma má idéia. Vazamentos de desempenho, memória e recursos, facilidade de implementação, facilidade de uso e facilidade de raciocínio, todos argumentam contra call/cc. Se existe realmente um recurso de controle diferenciado para implementar como primitivo, com outros relegados para bibliotecas, não é call/cc.

David Nolen escreveu uma biblioteca de continuações delimitada para Clojure. Experimente!

delimc

Uma biblioteca de continuações delimitada para o Clojure 1.4.0 (e 1.3.0). Porções baseadas em cl-cont por Slava Akhmechet ( http://defmacro.org ) ...

Frank Shearar
fonte
2

Embora o Clojure não tenha continuações ou corotinas de primeira classe incorporadas como um recurso principal, é possível implementar o seu próprio.

Por exemplo, core.async é uma biblioteca Clojure que implementa o modelo CSP (Concurrent Sequential Processes). Ele usa uma gomacro para transformar o código em uma máquina de estado. Embora não sejam exatamente as rotinas em si, elas podem ser usadas para implementar os mesmos padrões.

Há também o pulley.cps , um compilador de macro que eu criei que transforma o código Clojure (via cps/ cps-fnmacros) escrito em estilo direto no estilo de passagem de continuação. Que eu saiba, é o programa Clojure com tema de continuação mais completo. Ele suporta ligação dinâmica, exceções, chamadas entre o código nativo e o transformado (embora a continuação não seja mantida entre contextos). No momento, apenas continuações abortivas (ou seja, tradicionais call-cc) são suportadas, mas tenho planos de implementar continuações delimitadas no futuro.

Embora o pulley.cps não forneça diretamente rotinas em si, call-ccé relativamente simples implementar suas próprias. De fato, um dos exemplos é uma implementação simples da multitarefa cooperativa . Isso é aprofundado no exemplo do CSP . Há também um exemplo de pingue-pongue , mas é mais um exemplo de otimização de chamada de cauda do que corotinas.

Obviamente, esses tipos de transformações são mais eficazes quando aplicados a todo o programa. Infelizmente, isso não é possível apenas com macros, localizadas. Mesmo assim, até transformações localizadas podem ser muito eficazes.

Nathan Davis
fonte
1

O Clojure possui continuações ou corotinas para executar tarefas como ping-ponging sem sobrecarga de pilha?

Pergunta antiga, por isso não tenho certeza se esse recurso estava disponível no momento, mas para quem deseja implementar algum tipo de funcionalidade "pingue-pongue", confira o trampolim !

Acabei de descobri-lo como uma resposta à minha pergunta sobre o estilo eficiente de passagem de continuação em Clojure, aqui: /programming/50952443/continuation-passing-style-does-not-seem-to-make-a -diferença-de-clojure / 50955276 # 50955276 e acho que é apenas o trabalho. Eu tinha ouvido falar sobre isso há um tempo, mas nunca investiguei completamente. Mais me engana. Ao contrário de muitas das outras soluções propostas, ele simplesmente funciona .

====== PS. Cargas de informações sobre tutoriais on-line], aqui estão algumas que eu achei úteis

alex gian
fonte
1
talvez linkify trampolim para apontar para a documentação?
esoterik