Question

J'aimerais avoir une version de lambda, appelé lambda-r, à partir duquel vous pouvez return.Un exemple:

(+ ((lambda-r ()
    (return 1)
    2)) 5)

Cela donnerait la valeur 6.Bien que vous puissiez vous attendre à ce que la valeur soit 7, elle est 6 car 1 est renvoyé par l'expression lambda avant que 2 ne soit atteint.

Voici un exemple du type de transformation que je recherche.Disons que l'on utilise lambda-r comme suit:

(lambda-r (a b)
    (return a)
    (+ a b))

Je veux qu'il soit transformé comme ceci :

(call/cc (lambda (k)
       (define return (lambda (v)
                        (k (lambda (a b)
                             v))))
       (lambda (a b)
         (return a)
         (+ a b))))

Cela pourrait également être exprimé avec une expression let au lieu d'une définition interne, mais j'utilise la définition par souci de clarté.

Notez que le code ci-dessus fonctionne réellement comme prévu. Le problème c'est que j'ai du mal à m'exprimer lambda-r comme un macro.La raison est que je veux k et v pour être hygiénique, mais je ne veux pas return pour être hygiénique.

Ma macro du moment est la suivante :

(define-syntax lambda-r
  (syntax-rules (return)
    [(_ (var ...) body ...)
     (call/cc (lambda (k)
           (define return (lambda (v)
                            (k (lambda (var ...)
                                 v))))
           (lambda (var ...)
             body ...)))
     ]))

Ce qui ne marche pas parce que return est traité de manière hygiénique et n'est donc pas directement visible lors de l'utilisation lambda-r.Donc (lambda-r () (return 1)) donne une erreur qui dit que return n'est pas un identifiant valide.


Modifier:Grâce à la réponse de Nathan Sanders, je comprends mieux ce que je dois faire ici.Cependant, je ne comprends pas entièrement les procédures suivantes et, par conséquent, je n'ai pas encore réussi à faire fonctionner cela.J'apprécierais vraiment que vous puissiez m'expliquer/me diriger vers des ressources qui expliquent ce qui suit :

  • le syntax procédure
  • le datum->syntax/syntax->datum procédures

Modifier:Peu importe, je l'ai maintenant :)

Était-ce utile?

La solution

Ce que tu veux c'est syntax-case au lieu de syntax-rules.

La définition du R6RS donne quelques exemples, notamment une section sur les conversions syntaxe-objet et donnée, c'est ce que vous voulez.Vous devriez être capable d'adapter le loop avec break exemple à votre return.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top