Question

L'article de Wikipedia sur Continuation dit:
"Dans n'importe quelle langue qui prend en charge fermetures, il est possible d'écrire des programmes dans la continuation passing style et manuellement mettre en œuvre call/cc."

Soit c'est vrai et j'ai besoin de savoir comment le faire ou il n'est pas vrai et que la déclaration doit être corrigée.

Si cela est vrai, merci de me montrer comment mettre en œuvre call/cc en Lua, car je ne vois pas comment.

Je pense que je serais capable de mettre en œuvre call/cc manuellement si Lua a la coroutine.clone fonction comme expliqué ici.

Si les fermetures ne sont pas suffisantes pour mettre en œuvre call/cc, alors quoi d'autre est-il nécessaire?

Le texte ci-dessous est facultatif.
P. S.:Lua a one-shot des poursuites avec ses coroutine table.Une coroutine.clone fonction me permettrait de le clone de l'appeler plusieurs fois, ce qui en fait effectivement appel/cc possible (à moins que j'ai mal compris call/cc).Cependant que le clonage fonction n'existe pas dans Lua.Quelqu'un sur le Lua canal IRC suggéré que j'utilise le Pluton de la bibliothèque (elle met en œuvre la sérialisation) pour organiser une coroutine, copier et ensuite unmarshal et de l'utiliser de nouveau.Alors que ce serait sans doute le travail, je suis plus intéressé à l'examen théorique de la mise en œuvre de call/cc et dans la recherche de ce qu'est le réel de l'ensemble minimal de fonctionnalités qu'une langue doit avoir afin de permettre sa mise en œuvre manuelle.

EDIT 1: Ok les gens, aidez-moi ici, ce qui m'a pris beaucoup de temps parce que je ne connais pas un Régime, mais j'ai trouvé quelque chose qui devrait nous aider à sortir.S'il vous plaît regardez les codes ci-dessous.Le premier est un programme de Régime, le second est le même programme mais en Lua.
J'espère que cela va nous aider.Je crois que nous sommes très de près.

P. S.:Ces exemples sont tirés du premier exemple sur l'article de Wikipedia sur CallCC. Schéma de version

(define call/cc call-with-current-continuation)

; callcc CPS-transformed (thanks to the people from the #scheme channel at freenode.net)
(define cpscallcc
  (lambda (consumer k)
    (let ((cc (lambda (result) (k result))))
      (consumer cc k))))

; this is the continuation we will use to display the "returned" values
(define main-continuation
  (lambda (result)
    (display "--> ")
    (display result)
    (newline)))

; define f function non-CPS
(define (f return)
  (return 2)
  3)

; these are my past attempts at defining a CPS f function
;(define (cps-f return k)
;  (k (return 2)) 3)
;(define (cps-f return k)
;  (k (lambda ()
;       (return 2)
;       3)))

; this is what I came up with - I'm not sure if this is correctly CPS-transformed but I     believe so
(define (cps-f return k)
  (return 2)
  (k 3))

; call the non-CPS f function
(display (f (lambda (x) x))) ; displays 3
(newline)

; call the non-CPS f function with call/cc (I don't understand what this does)
(display (call/cc f)) ; displays 2
(newline)

; now call the CPS version of the f function
(cps-f (lambda (x) x) main-continuation)  ; displays --> 3

; now call the CPS version of the f function with the CPS version of call/cc
(cpscallcc cps-f main-continuation)  ; displays --> 2 but then it also displays --> 3 afterwards -> I'm not sure why it displays the 3 afterwards, as it should only display the 2 just like the non-CPS versions above



Lua version

-- callcc CPS-version
cpscallcc = function(consumer, k)
    local cc = function(result)
        return k(result)  -- ?or k(result)
    end
    return consumer(cc, k)  -- ?or return consumer(cc,k)
end

-- define f function non-CPS
f = function(ret)
    ret(2)
    return 3
end

-- define f function CPS-version (again, not sure this is correct)
cps_f = function(ret, k)
    ret(2)
    k(3)
end

-- call the non-CPS f function
print(f(function(x) return x end))

-- we cant call the non-CPS f function with callcc because
-- Lua doesnt have callcc, but the line below displays the correct expected output (maybe by accident)
--cpscallcc(f, print)

-- now call the CPS version of the f function
cps_f( function(x) return x end, print )  -- displays 3

; now call the CPS version of the f function with the CPS version of call/cc
cpscallcc( cps_f, print) -- displays 2 and then 3 just like the Scheme version!!
-- so apparently the translation from Scheme to Lua is correct...



Je suis l'aide de DrScheme et Lua pour Windows - pour toute personne qui veut aider à sortir ces deux facile à télécharger et installer les outils qui fonctionnent, tout simplement.

Était-ce utile?

La solution

Il y a deux conditions préalables à mettre en œuvre manuellement call/cc par la Wikipédia cite:

  1. la langue doit prendre en charge les fermetures
  2. vous devez écrire votre programme dans le prolongement, passant du style (CPS)

Je soupçonne que vous ne serez pas comme #2.

Écrire votre programme dans le prolongement, passant du style:

  1. Chaque fonction doit prendre une continuation argument
  2. Les fonctions doivent retourner en les appelant par leurs continuation

Ainsi, l'utilisation de k comme le nom de la poursuite de l'argument, une fonction ressemblerait à:

function multiplyadd(k, x, y, z) return k(x * y + z) end

Le toplevel peut utiliser print comme son prolongement, de sorte que l'invocation multiplyadd au plus haut niveau ressemblerait à:

multiplyadd(print, 2, 4, 1)

Avec que les échafaudages, nous pouvons définir call/cc

function callcc(k,f) return f(k,k) end

Remarque que ci-dessus multiplyadd en fait cheats depuis * et + ne sont pas dans le CPS.Il est très fastidieux d'ajouter tous les opérateurs dans le CPS forme, remplacer tous les Lua fonctions de la bibliothèque avec CPS équivalents, et de la traduire et de générer tout le code de la scp;voir les détails ici.

Autres conseils

Je suppose que vous avez oublié la partie sur l'écriture de votre programme dans le prolongement de passage style.Une fois que vous avez call/cc est trivial (en Lua ou dans toute autre langue), que la suite sera un paramètre explicite à toutes les fonctions (call/cc inclus).

PS:en plus de fermetures, vous avez également besoin d'une bonne queue appels de programme dans le prolongement passant du style.

Répondre à la question au sujet des plans pour le call/cc en Lua:Il n'y a pas de plans pour le call/cc en Lua.La capture d'une poursuite est trop cher ou demander un code analsis bien au-delà de ce que le Lua compilateur peut faire.Il y a aussi le problème que Lua continuations peut inclure des pièces en C.

Avec les coroutines, cependant, nous pouvons déjà mettre en œuvre l'appel/ce1 en Lua (one-shot suites).Qui est assez bon pour de nombreuses utilisations de continuations.

La phrase clé est

Il est possible de mettre en œuvre des programmes dans continuation passing style

(C'est moi qui souligne.) Vous faites cela en prenant régulièrement des "direct-style" programmes et de leur conversion à la poursuite de passage de style (CPS) par un programme de transformation appelé le CPS transformer.L'essentiel est que le CPS de transformation de call/cc une fonction simple.

Ce n'est pas pratique pour les programmeurs. Le CPS transformer a deux utilisations:

  • Comme une idée théorique pour l'étude des fonctions du langage, en particulier les opérateurs de contrôle
  • Comme un passage dans un compilateur qui utilise CPS comme langage intermédiaire

Vous ne voulez pas aller n'importe où près de faire CPS transforme sur le code Lua, surtout pas par la main.

il est possible:Tapuscrit-à-Lua Compilateur https://github.com/roblox-ts/roblox-ts + appelez-cc dans le JS https://github.com/zaoqi/callcc.js/blob/master/callcc.js

Voici ma cps-convertir dans le schéma, il suffit de passer chaque fonction que vous voulez convertir.

(define (cps-convert function . functions)
  # Since "help" is called at 2 different places...
  (define (help) (error "syntax: (cps-convert f1 f2 ...)"))
  # Single function converter
  (define (convert func)
    # "name" contains the function's name prefixed with "cps-"
    (let ([name (string->symbol
                          (string-append "cps-" (symbol->string func)))])
      # Dirty hack to define "cps-*" in the global environment
     `(eval '(begin
                   # Necessary to prevent the function from being evaluated
                   (define ,name #f)
                                # Magic
                   (set! ,name (lambda (k . args) (k (func args)))))
                 # Global environment
                 (interaction-environment))))
  # Prerequisite... Call help if condition not met
  (if (symbol? function)
      # function is a symbol
      (cond
        # If there is only one function to convert
        [(null? functions) (convert function)]
        # Else ensure every other "functions" are symbols and convert each
        [(every symbol? functions) (apply convert function functions)]
        # Oops! Condition not met!
        [else (help)])
      # Else clause from previous "if"
      (help)))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top