2010-04-14 7 views
3

J'ai une macro Scheme et une longue liste, et je voudrais mapper la macro sur la liste, comme s'il s'agissait d'une fonction. Comment puis-je faire cela en utilisant R5RS?Comment mapper une macro dans une liste dans Scheme?

La macro accepte plusieurs arguments:

(mac a b c d) 

La liste a

(define my-list ((a1 b1 c1 d1) 
       (a2 b2 c2 d2) 
       ... 
       (an bn cn dn))) 

et je voudrais avoir ceci:

(begin 
    (mac a1 b1 c1 d2) 
    (mac a2 b2 c2 d2) 
    ... 
    (mac an bn cn dn)) 

(Soit dit en passant, comme vous peut voir que je voudrais épisser la liste des arguments aussi)

+1

Je pense que rendre votre question plus concrète pourrait être utile. –

+0

Qu'est-ce que a1 b1 ...? Sont-ils atomiques? Sont-ils du code? Sans en savoir plus sur les données et la macro z5H a probablement la meilleure réponse. – Davorak

+0

Aucune restriction sur ce que a1 b1 ... sont. Pourrait être des atomes, pourrait être des listes, peu importe ... – josh

Répondre

1

expansion sur la réponse de z5h d'utiliser eval, les méthodes ci-dessous montrent comment écrire une macro carte-macro si interaction environnement mis en œuvre dans la version de r5rs en cours d'utilisation:

(define test-list '((1 2 3 4) 
        (5 6 7 8))) 

;Or if your version of scheme implments interaction-environment then: 
(define-syntax trade 
    (syntax-rules() 
    ((_ a b c d) (display (list b a d c))))) 

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
;Careful this is not really mapping. More like combined map and apply. 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
(define-syntax map-macro 
    (syntax-rules() 
    ((_ mac ls) (let ((mac-list (map (lambda (lst) (cons 'trade lst)) ls))) 
          (eval 
          `(begin 
           ,@mac-list) 
          (interaction-environment)))) 
         )) 

(map-macro trade test-list) 
;outputs: (2 1 4 3)(6 5 8 7) 

Alors que la dernière carte appel -macro évalue les suivantes:

Ce qui finit par être évalué à partir (carte-macro-liste de test du commerce) est:

(begin 
    (trade 1 2 3 4) 
    (trade 5 6 7 8)) 

Ce qui est pas tout à fait une carte, mais je crois cela répond à votre question.

+0

Cela signifie donc que je ne peux pas choisir d'écrire une macro "map-syntax" qui serait itérativement (dans la macro elle-même) se développer jusqu'à ce que mac soit développé pour tous les membres de la liste? (Bien sûr, je devrais passer la liste littéralement à la macro, et non dans une variable!) – josh

+1

Vous pouvez effectivement écrire une carte-macro si vous avez interaction-environnement dans votre version préférée du schéma R5RS. interaction-environment est optionnel dans la spécification R5RS. Il existe dans DrScheme ou quel que soit le nouveau nom. J'ai édité ma réponse pour donner un exemple d'une macro de carte-macro. – Davorak

0

Would quelque chose comme

(map (lambda (l) (mac (car l) (caar l) (caaar l) (caaaar l))) mylist)

travail?

+0

La macro accepte varargs, donc la solution ci-dessus entraîne une erreur. – josh

+0

Je ne vois pas pourquoi cela signifie que vous auriez une erreur. Voulez-vous dire que les listes, à l'intérieur de ma liste, pourraient être plus ou moins longues? –

+1

@Jay Korninek la macro peut manipuler ce qui est à l'intérieur de a1 b1 ... puisque je ne pense pas que nous pouvons supposer qu'ils sont atomiques. – Davorak

2

extensions syntaxiques sont développés dans formes de base au début de l'évaluation (avant la compilation ou de l'interprétation) par un expanseur de syntaxe. -Dybvig, « Le langage de programmation Scheme .

Une macro fonctionne sur la syntaxe Cela se produit avant la compilation ou l'exécution Il vous donne une autre façon d'écrire le même code

Une fonction fonctionne sur les variables et.. valeurs (qui peuvent être des listes, des atomes, des nombres, etc.) dont la valeur est connue lorsque la fonction est appelée

Donc, le mappage d'une macro n'a pas de sens. est arrivé il y a longtemps.

Si vous avez besoin de quelque chose pour écrire du code pour vous et l'évaluer lors de l'exécution, il se peut que ce soit l'un de ces cas où vous avez besoin de eval.

+0

Je crois qu'il veut agrandir la macro avant la compilation (non?). Je ne suis pas sûr de Scheme, mais j'en ai fait beaucoup dans Common Lisp avec defmacro (le code dans defmacro utiliserait beaucoup d'autres fonctions pour transformer les expressions S (même les hashtables globaux utilisés!)). Une macro définirait plusieurs fonctions ... – Jay

Questions connexes