2010-07-10 3 views
1

Je voudrais avoir une version de lambda, appelée lambda-r, à partir de laquelle vous pouvez return. Un exemple:Comment faire juste une partie d'une macro hygiénique

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

Cela donnerait la valeur 6. Bien que vous puissiez vous attendre à ce que la valeur soit 7, c'est 6 parce que 1 est renvoyé de l'expression lambda avant que 2 soit atteint.

Voici un exemple du type de transformation que je recherche. Disons que l'on devait utiliser 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 aussi être exprimé avec un laissez-expression au lieu d'une définir interne, mais J'utilise le définir pour des raisons de clarté.

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

Ma macro au 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 fonctionne pas parce que return est traité hygiéniquement, et par conséquent ne sont pas directement visibles lors de l'utilisation lambda-r. Donc (lambda-r() (return 1)) donne une erreur qui dit que return n'est pas un identificateur valide. Edit: Merci à la réponse de Nathan Sanders, je suis plus près de comprendre ce que je dois faire ici. Cependant, je ne comprends pas complètement les procédures suivantes et, par conséquent, je n'ai pas encore réussi à le faire fonctionner. Je vous en serais reconnaissant si vous pouviez expliquer/me diriger vers des ressources qui expliquent ce qui suit:

  • la procédure syntax
  • les datum->syntax/syntax->datum procédures

Edit: de Nevermind - J'ai maintenant :)

Répondre

2

Ce que vous voulez est syntax-case au lieu de syntax-rules.

The R6RS definition donne quelques exemples, notamment a section on syntax-object and datum conversions, ce qui est ce que vous voulez. Vous devriez pouvoir adapter l'exemple loop w/break à votre return.

+0

Merci, je pense que c'est ce que je cherche. J'ai lu cette page et c'est un peu difficile à digérer; pouvez-vous expliquer ce que fait la procédure 'syntaxe '? Une description plus facile à comprendre de 'with-syntax', et' datum-> syntax'/'syntax-> datum' serait également utile. – Cam

+0

En fait, nevermind - Je sais comprendre ces termes. Merci! – Cam

+0

Je ne peux plus éditer ce commentaire, mais ça m'embête toujours: je * comprends maintenant ces termes :) – Cam

Questions connexes